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