1 /* 2 * Redistribution and use of this software and associated documentation ("Software"), with or 3 * without modification, are permitted provided that the following conditions are met: 4 * 5 * 1. Redistributions of source code must retain copyright statements and notices. Redistributions 6 * must also contain a copy of this document. 7 * 8 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of 9 * conditions and the following disclaimer in the documentation and/or other materials provided with 10 * the distribution. 11 * 12 * 3. The name "Exolab" must not be used to endorse or promote products derived from this Software 13 * without prior written permission of Intalio, Inc. For written permission, please contact 14 * info@exolab.org. 15 * 16 * 4. Products derived from this Software may not be called "Exolab" nor may "Exolab" appear in 17 * their names without prior written permission of Intalio, Inc. Exolab is a registered trademark of 18 * Intalio, Inc. 19 * 20 * 5. Due credit should be given to the Exolab Project (http://www.exolab.org/). 21 * 22 * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 24 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTALIO, INC. OR ITS 25 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 29 * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 * 31 * Copyright 1999, 2000 (C) Intalio, Inc. All Rights Reserved. 32 * 33 * $Id$ 34 */ 35 package org.exolab.castor.xml.util; 36 37 import org.castor.xml.XMLNaming; 38 import org.exolab.castor.xml.AbstractXMLNaming; 39 40 /** 41 * The default implementation of org.exolab.castor.xml.Naming 42 * 43 * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a> 44 * @version $Revision$ $Date: 2003-03-03 00:05:44 -0700 (Mon, 03 Mar 2003) $ 45 */ 46 public final class DefaultNaming extends AbstractXMLNaming implements XMLNaming { 47 48 /** 49 * The lower case style with hyphens to separate words. <I>Default</I> <BR /> 50 * <B>examples:</B><BR /> 51 * "Blob" becomes "blob" and "DataSource" becomes "data-source". 52 */ 53 public static final short LOWER_CASE_STYLE = 0; 54 55 /** 56 * The mixed case style with uppercase characters to separate words. <BR> 57 * <B>examples:</B><BR> 58 * "Blob" becomes "blob" and "DataSource" becomes "dataSource". 59 */ 60 public static final short MIXED_CASE_STYLE = 1; 61 62 private short _style = LOWER_CASE_STYLE; 63 64 public DefaultNaming() { 65 super(); 66 } 67 68 /** 69 * Sets the style for this DefaultNaming. Valid options are as follows 70 * 71 * <pre> 72 * DefaultNaming.LOWER_CASE_STYLE 73 * DefaultNaming.MIXED_CASE_STYLE 74 * </pre> 75 * 76 * @param style the style to use 77 */ 78 public void setStyle(final short style) { 79 switch (style) { 80 case MIXED_CASE_STYLE: 81 case LOWER_CASE_STYLE: 82 _style = style; 83 break; 84 default: 85 throw new IllegalArgumentException("Invalid option for DefaultNaming#setStyle."); 86 } 87 } 88 89 /** 90 * Creates the XML Name for the given class. It would be nearly impossible for this method to 91 * please every one, so I picked common "de-facto" XML naming conventions. This can be overridden 92 * by either extending org.exolab.castor.xml.Naming and implementing the proper methods, or by 93 * ClassDescriptors for your classes. 94 * 95 * @param c the Class to create the XML Name for 96 * @return the xml name representation of the given String <BR> 97 * <B>examples:</B><BR> 98 * "Blob" becomes "blob" and "DataSource" becomes "data-source". 99 * @deprecated extracting name parts from a Class is responsibility of JavaNaming 100 */ 101 @Override 102 public String createXMLName(final Class<?> c) { 103 UnsupportedOperationException e = 104 new UnsupportedOperationException("Method has moved to JavaNaming!"); 105 throw e; 106 // -- create default XML name 107 // String name = c.getName(); 108 // int idx = name.lastIndexOf('.'); 109 // if (idx >= 0) { 110 // name = name.substring(idx+1); 111 // } 112 // return toXMLName(name); 113 } 114 115 /** 116 * Converts the given name to an XML name. It would be nearly impossible for this method to please 117 * every one, so I picked common "de-facto" XML naming conventions. This can be overridden by 118 * either extending org.exolab.castor.xml.Naming and implementing the proper methods, or by 119 * ClassDescriptors for your classes. 120 * 121 * @param name the String to convert to an XML name 122 * @return the xml name representation of the given String <BR> 123 * <B>examples:</B><BR> 124 * "Blob" becomes "blob" and "DataSource" becomes "data-source". 125 */ 126 @Override 127 public String toXMLName(final String name) { 128 if (name == null) { 129 return null; 130 } 131 if (name.length() == 0) { 132 return name; 133 } 134 if (name.length() == 1) { 135 return name.toLowerCase(); 136 } 137 138 // -- Follow the Java beans Introspector::decapitalize 139 // -- convention by leaving alone String that start with 140 // -- 2 uppercase characters. 141 if (Character.isUpperCase(name.charAt(0)) && Character.isUpperCase(name.charAt(1))) { 142 return name; 143 } 144 145 // -- process each character 146 StringBuilder cbuff = new StringBuilder(name); 147 cbuff.setCharAt(0, Character.toLowerCase(cbuff.charAt(0))); 148 149 boolean ucPrev = false; 150 for (int i = 1; i < cbuff.length(); i++) { 151 char ch = cbuff.charAt(i); 152 if (Character.isUpperCase(ch)) { 153 if (ucPrev) { 154 continue; 155 } 156 ucPrev = true; 157 if (_style == LOWER_CASE_STYLE) { 158 cbuff.insert(i, '-'); 159 ++i; 160 cbuff.setCharAt(i, Character.toLowerCase(ch)); 161 } else { 162 ++i; 163 } 164 } else if (ch == '.') { 165 // -- do not add '-' if preceeded by '.' 166 ucPrev = true; 167 } else { 168 ucPrev = false; 169 } 170 } 171 return cbuff.toString(); 172 } 173 174 }