View Javadoc
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 }