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 2001 (C) Intalio, Inc. All Rights Reserved. 32 * 33 * $Id$ 34 */ 35 package org.exolab.castor.builder; 36 37 import java.util.Hashtable; 38 39 import org.castor.xml.JavaNaming; 40 import org.exolab.castor.xml.schema.ComplexType; 41 import org.exolab.castor.xml.schema.ElementDecl; 42 import org.exolab.castor.xml.schema.Group; 43 import org.exolab.castor.xml.schema.ModelGroup; 44 import org.exolab.castor.xml.schema.Structure; 45 46 /*** 47 * A simple class used for creating class names for unnamed Groups in XML Schema. 48 * 49 * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a> 50 * @version $Revision$ $Date: 2006-04-25 15:08:23 -0600 (Tue, 25 Apr 2006) $ 51 */ 52 public final class GroupNaming { 53 54 /** 55 * A HashTable of HashTables that keeps track of group names for each package. 56 */ 57 private Hashtable<String, Hashtable<Group, String>> _packageGroupNames = null; 58 59 /** 60 * JavaNaming to be used. 61 * 62 * @since 1.1.3 63 */ 64 private JavaNaming _javaNaming; 65 66 67 /** 68 * Creates a new GroupNaming. 69 * 70 * @param javaNaming the {@link JavaNaming} to be used 71 */ 72 public GroupNaming(final JavaNaming javaNaming) { 73 _packageGroupNames = new Hashtable<String, Hashtable<Group, String>>(); 74 // JavaNaming was introduced @since 1.1.3 75 _javaNaming = javaNaming; 76 } // -- GroupNaming 77 78 /** 79 * Returns the qualified group name for a given Group instance and a package name; null if there 80 * isn't one already. 81 * 82 * @param group A Group instance 83 * @param packageName A package name 84 * @return The fully qualified group name for the Group instance/package name combination 85 */ 86 private String getGroupName(final Group group, final String packageName) { 87 Hashtable<Group, String> groupNames = _packageGroupNames.get(packageName); 88 if (groupNames == null) { 89 return null; 90 } 91 return groupNames.get(group); 92 } 93 94 /** 95 * Sets the qualified group name for a given Group instance and package name. 96 * 97 * @param group A Group instance 98 * @param packageName A package name 99 * @param name The fully qualified group name for the Group instance/package name combination 100 */ 101 private void putGroupName(final Group group, final String packageName, final String name) { 102 Hashtable<Group, String> groupNames = _packageGroupNames.get(packageName); 103 if (groupNames == null) { 104 groupNames = new Hashtable<Group, String>(); 105 _packageGroupNames.put(packageName, groupNames); 106 } 107 groupNames.put(group, name); 108 } 109 110 /** 111 * Checks whether for a given group and package name combination an entry already exists. 112 * 113 * @param packageName A package name 114 * @param name A group name. 115 * @return True if a mapping already exists 116 */ 117 private boolean containsGroupName(final String packageName, final String name) { 118 Hashtable<Group, String> groupNames = _packageGroupNames.get(packageName); 119 if (groupNames == null) { 120 return false; 121 } 122 return groupNames.contains(name); 123 } 124 125 /** 126 * Creates a class name for the given Group. A null value will be returned if a name cannot be 127 * created for the group. 128 * 129 * @param group the group to create a class name for 130 * @param packageName the package name for this group 131 * @return the class name for the given Group. 132 */ 133 public String createClassName(final Group group, final String packageName) { 134 String name = group.getName(); 135 if (name != null) { 136 return _javaNaming.toJavaClassName(name); 137 } 138 name = getGroupName(group, packageName); 139 if (name != null) { 140 return name; 141 } 142 143 Structure parent = group.getParent(); 144 if (parent == null) { 145 return null; 146 } 147 148 boolean addOrder = true; 149 switch (parent.getStructureType()) { 150 case Structure.GROUP: 151 name = createClassName((Group) parent, packageName); 152 break; 153 case Structure.MODELGROUP: 154 name = ((ModelGroup) parent).getName(); 155 name = _javaNaming.toJavaClassName(name); 156 addOrder = false; 157 break; 158 case Structure.COMPLEX_TYPE: 159 name = getClassName((ComplexType) parent); 160 addOrder = false; 161 break; 162 default: 163 break; 164 } 165 166 if (name != null) { 167 if (addOrder) { 168 String order = group.getOrder().toString(); 169 name += _javaNaming.toJavaClassName(order); 170 } 171 172 int count = 2; 173 String tmpName = name; 174 while (containsGroupName(packageName, name)) { 175 name = tmpName + count; 176 ++count; 177 } 178 putGroupName(group, packageName, name); 179 } 180 return name; 181 } // -- createClassName 182 183 /** 184 * Returns the class name for the given ComplexType. 185 * <p> 186 * If the ComplexType instance is named, simply return the name of the ComplexType. 187 * <p> 188 * If it is not named (in other words, if it is an anonymous ComplexType definition), check for 189 * the name of the containing element (definition). 190 * 191 * @param complexType the ComplexType for which to return a class name 192 * @return the class name for the given ComplexType 193 */ 194 private String getClassName(final ComplexType complexType) { 195 // -- if complexType has name, simply return it 196 String name = complexType.getName(); 197 if (name != null) { 198 return _javaNaming.toJavaClassName(name); 199 } 200 201 // -- otherwise get name of containing element 202 Structure parent = complexType.getParent(); 203 if (parent != null && parent.getStructureType() == Structure.ELEMENT) { 204 name = ((ElementDecl) parent).getName(); 205 } 206 207 if (name != null) { 208 name = _javaNaming.toJavaClassName(name); 209 } 210 return name; 211 } // -- getName 212 213 } // -- class GroupNaming