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