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-2007 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:
042: /*
043: * SymbolTransaction.java
044: *
045: * Created on February 3, 2001, 8:08 AM
046: */
047:
048: package org.netbeans.modules.uml.integration.ide.events;
049:
050: import org.netbeans.modules.uml.core.support.umlutils.ElementLocator;
051: import java.io.File;
052: import java.util.StringTokenizer;
053:
054: import org.netbeans.modules.uml.integration.ide.UMLSupport;
055: import org.netbeans.modules.uml.integration.ide.JavaClassUtils; //import org.netbeans.modules.uml.integration.ide.Log;
056: import org.netbeans.modules.uml.core.IUMLCreationFactory;
057: import org.netbeans.modules.uml.core.metamodel.core.constructs.IClass;
058: import org.netbeans.modules.uml.core.metamodel.core.foundation.IElement;
059: import org.netbeans.modules.uml.core.metamodel.core.foundation.INamedElement;
060: import org.netbeans.modules.uml.core.metamodel.core.foundation.IPackage;
061: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IClassifier;
062: import org.netbeans.modules.uml.core.metamodel.structure.IProject;
063: import org.netbeans.modules.uml.core.support.umlsupport.Log;
064: import org.netbeans.modules.uml.core.support.umlutils.ETList;
065: import org.netbeans.modules.uml.ui.support.ProductHelper;
066:
067: /**
068: * SymbolTransaction is used to handle the state of storing GDPro information.
069: *
070: * Revision History
071: * No. Date Who What
072: * --- ---- --- ----
073: * 1 2002-05-21 Darshan Changed .getUMLCreationFactory() call from
074: * application to product.
075: * 2 2002-06-19 Darshan Removed unnecessary conversions between Java
076: * and UML fully scoped class/package names.
077: * @todo Cleanup all commented out code.
078: * @author tspiva
079: * @version
080: */
081: public class SymbolTransaction {
082: private IClassifier mGDSymbol = null;
083:
084: // Changed for wolverine, currently active IProject
085: //protected static IProject aProj = null;
086:
087: /**
088: * Creates and initializes a new symbol transaction. Describe is
089: * required to specify where to search for the symbol data.
090: * @param system The system to use.
091: */
092: public SymbolTransaction() {
093: this (null);
094: }
095:
096: /**
097: * Creates and initializes a new symbol transaction. The Describe is
098: * required to specify where to search for the symbol data.
099: * @param info The symbol to find or create it it does not exist.
100: * @param system The system to use.
101: */
102: public SymbolTransaction(ClassInfo info) {
103: //setProject();
104: if (info != null) {
105: setSymbol(info);
106: }
107: }
108:
109: protected void finalize() {
110: mGDSymbol = null;
111: }
112:
113: public IClassifier getSymbol() {
114: return mGDSymbol;
115: }
116:
117: /**
118: * Sets the Describe system to use when retrieving the symbols information.
119: * Therefore, the symbol will also reside in the Describe system.
120: * @param value The Describe system.
121: */
122: // protected void setProject() {
123: // aProj = GDProSupport.getCurrentProject();
124: // }
125:
126: /**
127: * Sets the symbol to use for the transaction. A transaction only start
128: * when a symbol has been set. I commit transaction <B>MUST</B> be called
129: * after the transaction is completed.
130: *
131: * @param sym The symbol to be used during the transaction.
132: * @see #commitChanges
133: */
134: public void setSymbol(IClassifier sym) {
135: mGDSymbol = sym;
136: }
137:
138: /**
139: * Sets the symbol to use for the transaction. Describe will be used to
140: * locate the symbol specified in the ClassInfo. If a Describe symbol is
141: * not found then a new symbol is created. A transaction only start when a
142: * symbol has been set. I commit transaction <B>MUST</B> be called after
143: * the transaction is completed.
144: *
145: * @param sym The symbol to be used during the transaction.
146: * @see #commitChanges
147: */
148: public void setSymbol(final ClassInfo info) {
149: Log.out("Inside setSymbol ..");
150: // First set the symbol to null to allow the current symbol to be GC
151: mGDSymbol = null;
152: IProject system = null; /* NB60TBD UMLSupport.getProjectForPath(info.getFilename()); */
153: // IProject system = UMLSupport.getCurrentProject();
154: // IProject system = info.getProject();
155: if (system != null) {
156: // Get the UML qualified name in UML
157: setSymbol(createClass(info.getName(), info.getPackage(),
158: info.isInterface(), info.isEnumeration(), null,
159: info.getChangeType(), info.getFilename()));
160: }
161: }
162:
163: /**
164: * Retrieves an inner class from is transactions Describe symbol. If the
165: * inner class does not exist then a new class symbol is created and the
166: * transaction is returned.
167: * @param info The inner class to retieve.
168: * @return The inner class transaction.
169: */
170: public SymbolTransaction getInnerClass(ClassInfo info) {
171: SymbolTransaction innerTrans = new SymbolTransaction(info);
172:
173: // Test if the found symbol already has the inner class association.
174: // If it does not create the association.
175: IClassifier outerSym = getSymbol();
176: IClassifier innerSym = innerTrans.getSymbol();
177:
178: try {
179: if ((outerSym != null) && (innerSym != null)) {
180: // Now it is possible for one class to play in multiple inner
181: // class relationships. So, if the inner class does not already
182: // in an inner class relationship with the outer class then put
183: // it in the inner class relationship.
184: Log.out("Trying to add the inner class ..... ");
185: boolean foundIt = findInnerClass(outerSym, innerSym);
186: Log.out("fountIt = " + foundIt);
187: if (!foundIt) {
188: innerSym.setOwner(outerSym);
189: }
190:
191: }
192: } catch (Exception ioE) {
193: Log.stackTrace(ioE);
194: }
195:
196: return innerTrans;
197: }
198:
199: // *************************************************************************
200: // Helper Methods
201: // *************************************************************************
202:
203: /**
204: * checks if the inner class with the given name already exists for this
205: * symbol
206: *
207: * @param clazz
208: */
209: public boolean findInnerClass(IClassifier clazz, IClassifier inner) {
210: ETList<INamedElement> els = clazz.getOwnedElements();
211:
212: int c = els.getCount();
213: for (int i = 0; i < c; ++i) {
214: IElement el = els.item(i);
215: if (el instanceof IClass) {
216: //IClass innerCl = (IClass) el;
217: IClass innerCl = (IClass) el;
218: if (innerCl.getName().equals(inner.getName())) {
219: Log.out("The inner class with the name "
220: + inner.getName() + " already exists in "
221: + clazz.getName());
222: return true;
223: }
224: } else {
225: Log.out("The owned element type is "
226: + el.getElementType());
227: }
228:
229: }
230: return false;
231: }
232:
233: public static IClassifier createClass(String name, String pk,
234: boolean isInterface, boolean isEnumeration, IProject proj,
235: int changeType, String file) {
236:
237: // First, try to find if the class already present
238: String qualifiedName = JavaClassUtils.formFullClassName(pk,
239: name);
240: IClassifier orig = JavaClassUtils
241: .findClassSymbol(qualifiedName);
242:
243: Log.out("createClass: name = " + name);
244: if (orig != null && JavaClassUtils.isReferenceClass(orig)
245: && changeType == ElementInfo.CREATE) {
246: Log.out("createClass: Found data type : " + name);
247: Log.out("createClass: Transforming data type");
248: orig = orig.transform(isInterface ? ClassInfo.DS_INTERFACE
249: : (isEnumeration ? ClassInfo.DS_ENUMERATION
250: : ClassInfo.DS_CLASS));
251: }
252:
253: // String fullyQName = qualifiedName.replaceAll("$", "::");
254: // orig = JavaClassUtils.findClassSymbol(fullyQName);
255:
256: if (orig != null || changeType != ElementInfo.CREATE) {
257: return orig;
258: }
259:
260: IUMLCreationFactory fact = getUMLCreationFactory();
261: IClassifier clazz = null;
262: if (isInterface) {
263: clazz = fact.createInterface(null);
264: } else if (isEnumeration) {
265: Log.out("createClass: Creating enumeration : " + name);
266: clazz = fact.createEnumeration(null);
267: } else {
268: Log.out("createClass: Creating class : " + name);
269: clazz = fact.createClass(null);
270: }
271:
272: if (proj == null)
273: proj = UMLSupport.getCurrentProject();
274:
275: // for inner classes set the parents as required
276: if (qualifiedName.indexOf("$") > 0) {
277: // find the last outer class
278: String parent = qualifiedName.substring(0, qualifiedName
279: .lastIndexOf("$"));
280: IClassifier cl = JavaClassUtils.findClassSymbol(parent);
281: if (cl != null) {
282: cl.addOwnedElement(clazz);
283: }
284: } else {
285: if (pk != null && !pk.trim().equals("")) {
286: IPackage pack = getClassPackage(pk, file);
287: pack.addOwnedElement(clazz);
288: } else {
289: proj.addOwnedElement(clazz);
290: }
291: }
292: Log.out("createClass: Setting class name to "
293: + JavaClassUtils.getInnerClassName(name));
294: clazz.setName(JavaClassUtils.getInnerClassName(name));
295:
296: return clazz;
297: }
298:
299: public static INamedElement getClassOwner(String qualifiedName) {
300: // for inner classes set the parents as required
301: if (qualifiedName.indexOf("$") > 0) {
302: // find the last outer class
303: String parent = qualifiedName.substring(0, qualifiedName
304: .lastIndexOf("$"));
305: IClassifier cl = JavaClassUtils.findClassSymbol(parent);
306: return cl;
307: } else {
308: String pk = JavaClassUtils.getPackageName(qualifiedName);
309: if (pk != null && !pk.trim().equals("")) {
310: IPackage pack = getClassPackage(pk, null);
311: return pack;
312: } else
313: return UMLSupport.getCurrentProject();
314: }
315: }
316:
317: // public IProject getProject() {
318: // return aProj;
319: // }
320:
321: public static IPackage getClassPackage(String pk, String filename) {
322: Log.out("getClassPackage(" + pk + ", " + filename + ")");
323: IUMLCreationFactory fact = getUMLCreationFactory();
324: // pk.replaceAll(".", "::"); not working
325: pk = JavaClassUtils.getQualifiedPackageName(pk);
326: StringTokenizer st = new StringTokenizer(pk, "::");
327: int i = 0;
328: IPackage prev = null;
329: IPackage pack = null;
330: String packName = null;
331:
332: IPackage base = null;
333: while (st.hasMoreTokens()) {
334: ++i;
335: prev = pack;
336: packName = st.nextToken();
337: pack = JavaClassUtils.findScopedPackage(packName, prev);
338: if (pack != null) // package already exists
339: continue;
340: // create new package
341: Log.out("Creating package " + packName);
342: pack = fact.createPackage(null);
343: pack.setName(packName);
344: if (i == 1 && prev == null) { // if first set the owner as proj
345: UMLSupport.getCurrentProject().addOwnedElement(pack);
346: } else {
347: prev.addOwnedElement(pack);
348: }
349:
350: // TODO:
351: // if (pack.getIsTopLevelPackage() || i == 1)
352: // base = pack;
353: // else
354: // Log.out(pack.getName() + " is not a top-level package");
355: }
356:
357: if (base != null && filename != null) {
358: File sourceDir = new File(filename);
359: while (i-- >= 0)
360: sourceDir = sourceDir.getParentFile();
361: Log.out("getClassPackage: Setting source directory for "
362: + base.getName() + " to " + sourceDir);
363: base.setSourceDir(sourceDir.toString());
364: Log.out("getClassPackage: New source directory for "
365: + base.getName() + " is " + base.getSourceDir());
366: }
367:
368: return pack;
369: }
370:
371: public static IUMLCreationFactory getUMLCreationFactory() {
372: IUMLCreationFactory fact = (IUMLCreationFactory) ProductHelper
373: .getProduct().getCreationFactory();
374: return fact;
375: }
376: }
|