001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.vmd.midp.codegen;
042:
043: import org.netbeans.modules.vmd.api.model.*;
044: import org.netbeans.modules.vmd.api.model.common.ValidatorPresenter;
045: import org.netbeans.modules.vmd.api.codegen.CodeNamePresenter;
046: import org.netbeans.modules.vmd.midp.components.MidpTypes;
047:
048: import java.util.HashSet;
049: import java.util.Collection;
050: import java.util.List;
051:
052: /**
053: * @author David Kaspar
054: */
055: public final class InstanceNameResolver {
056:
057: private InstanceNameResolver() {
058: }
059:
060: public static PropertyValue createFromSuggested(
061: DesignComponent component, String suggestedMainName) {
062: return createFromSuggested(component, suggestedMainName, null);
063: }
064:
065: public static PropertyValue createFromSuggested(
066: DesignComponent component, String suggestedMainName,
067: Collection<String> additionalReservedNames) {
068: assert component.getDocument().getTransactionManager()
069: .isAccess();
070: Collection<? extends CodeNamePresenter> presenters = component
071: .getPresenters(CodeNamePresenter.class);
072: if (presenters.isEmpty())
073: Debug
074: .warning("CodeNamePresenter is missing for",
075: component); // NOI18N
076: HashSet<String> names = new HashSet<String>();
077: gatherNames(component.getDocument().getRootComponent(),
078: component, names);
079: if (additionalReservedNames != null)
080: names.addAll(additionalReservedNames);
081:
082: suggestedMainName = checkForJavaIdentifierCompliant(suggestedMainName);
083: if (checkIfNameAlreadyReserved(presenters, suggestedMainName,
084: names)) {
085: int index = suggestedMainName.length();
086: while (index >= 1
087: && Character.isDigit(suggestedMainName
088: .charAt(index - 1)))
089: index--;
090: int number = index < suggestedMainName.length() ? Integer
091: .parseInt(suggestedMainName.substring(index)) : 1;
092: suggestedMainName = suggestedMainName.substring(0, index);
093:
094: suggestedMainName = findNumberedInstanceName(presenters,
095: suggestedMainName, number, names);
096: }
097: return MidpTypes.createStringValue(suggestedMainName);
098: }
099:
100: private static String findNumberedInstanceName(
101: Collection<? extends CodeNamePresenter> presenters,
102: String suggestedMainName, int number, HashSet<String> names) {
103: for (;; number++) {
104: String testName = suggestedMainName + number;
105: if (!checkIfNameAlreadyReserved(presenters, testName, names))
106: return testName;
107: }
108: }
109:
110: private static boolean checkIfNameAlreadyReserved(
111: Collection<? extends CodeNamePresenter> presenters,
112: String suggestedMainName, HashSet<String> names) {
113: for (CodeNamePresenter presenter : presenters) {
114: List<String> reservedNamesFor = presenter
115: .getReservedNamesFor(suggestedMainName);
116: if (reservedNamesFor != null)
117: for (String name : reservedNamesFor) {
118: if (names.contains(name))
119: return true;
120: }
121: }
122: return false;
123: }
124:
125: private static String checkForJavaIdentifierCompliant(
126: String instanceName) {
127: if (instanceName == null || instanceName.length() < 1)
128: return "object"; // NOI18N
129: StringBuffer buffer = new StringBuffer();
130: int index = 0;
131: if (Character.isJavaIdentifierStart(instanceName.charAt(0))) {
132: buffer.append(instanceName.charAt(0));
133: index++;
134: } else {
135: buffer.append('a'); // NOI18N
136: }
137: while (index < instanceName.length()) {
138: char c = instanceName.charAt(index);
139: if (Character.isJavaIdentifierPart(c))
140: buffer.append(c);
141: index++;
142: }
143: return buffer.toString();
144: }
145:
146: private static void gatherNames(DesignComponent component,
147: DesignComponent excludeComponent, HashSet<String> names) {
148: assert component.getDocument().getTransactionManager()
149: .isAccess();
150: if (component == excludeComponent)
151: return;
152: Collection<? extends CodeNamePresenter> presenters = component
153: .getPresenters(CodeNamePresenter.class);
154: for (CodeNamePresenter presenter : presenters) {
155: List<String> reservedNames = presenter.getReservedNames();
156: if (reservedNames != null)
157: names.addAll(reservedNames);
158: }
159: for (DesignComponent child : component.getComponents())
160: gatherNames(child, excludeComponent, names);
161: }
162:
163: public static Presenter createValidatorPresenter() {
164: return new ValidatorPresenter() {
165: @Override
166: protected void checkCustomValidity() {
167: InstanceNameResolver.checkValidity(getComponent()
168: .getDocument());
169: }
170: };
171: }
172:
173: private static void checkValidity(DesignDocument document) {
174: //XXX: build hotfix
175: // checkValidity (document.getRootComponent (), new HashSet<String> (), new HashSet<String> ());
176: }
177:
178: }
|