0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * The Original Software is NetBeans. The Initial Developer of the Original
0027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028: * Microsystems, Inc. All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: */
0041:
0042: /*
0043: * File : ClassInfo.java
0044: * Version : 1.5
0045: * Description : A metaclass for Java classes, used for transferring
0046: * information between IDE integrations and the Describe
0047: * IDE integration package.
0048: * Author : Trey Spiva
0049: */
0050: package org.netbeans.modules.uml.integration.ide.events;
0051:
0052: import java.io.File;
0053: import java.io.IOException;
0054: import java.lang.reflect.Modifier;
0055: import java.util.ArrayList;
0056: import java.util.Collections;
0057: import java.util.Comparator;
0058: import java.util.HashSet;
0059: import java.util.Hashtable;
0060: import java.util.List;
0061: import java.util.Iterator;
0062: import java.util.Vector;
0063: import java.util.logging.Level;
0064: import java.util.logging.Logger;
0065: import org.netbeans.modules.uml.core.metamodel.core.constructs.IClass;
0066: import org.netbeans.modules.uml.core.metamodel.core.constructs.IEnumeration;
0067: import org.netbeans.modules.uml.core.metamodel.core.constructs.IEnumerationLiteral;
0068: import org.netbeans.modules.uml.core.metamodel.core.foundation.IElement;
0069: import org.netbeans.modules.uml.core.metamodel.core.foundation.INamedElement;
0070: import org.netbeans.modules.uml.core.metamodel.core.foundation.IPackage;
0071: import org.netbeans.modules.uml.core.metamodel.diagrams.ICoreRelationshipDiscovery;
0072: import org.netbeans.modules.uml.core.metamodel.diagrams.IDiagram;
0073: import org.netbeans.modules.uml.core.metamodel.infrastructure.IDerivationClassifier;
0074: import org.netbeans.modules.uml.core.metamodel.infrastructure.IRelationFactory;
0075: import org.netbeans.modules.uml.core.metamodel.infrastructure.RelationFactory;
0076: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.ClassifierTemplateParameter;
0077: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IAssociation;
0078: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IAssociationEnd;
0079: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IAttribute;
0080: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IClassifier;
0081: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IDerivation;
0082: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IGeneralization;
0083: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IImplementation;
0084: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IInterface;
0085: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.INavigableEnd;
0086: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IOperation;
0087: import org.netbeans.modules.uml.core.metamodel.structure.IProject;
0088: import org.netbeans.modules.uml.core.metamodel.structure.ISourceFileArtifact;
0089: import org.netbeans.modules.uml.core.support.umlsupport.FileManip;
0090: import org.netbeans.modules.uml.core.support.umlsupport.FileSysManip;
0091: import org.netbeans.modules.uml.core.support.umlsupport.Log;
0092: import org.netbeans.modules.uml.core.support.umlutils.ETList;
0093: import org.netbeans.modules.uml.integration.ide.ChangeUtils;
0094: import org.netbeans.modules.uml.integration.ide.DiagramKind;
0095: import org.netbeans.modules.uml.integration.ide.JavaClassUtils;
0096: import org.netbeans.modules.uml.integration.ide.UMLSupport;
0097: import org.openide.ErrorManager;
0098: import org.openide.filesystems.FileObject;
0099: import org.openide.filesystems.FileUtil;
0100:
0101: /**
0102: * A metaclass for Java classes, used for transferring information between IDE
0103: * integrations and the Describe IDE integration package. This class is not
0104: * synchronized. If you use a single ClassInfo instance in multiple threads,
0105: * the responsibility for synchronization is with the caller.
0106: *
0107: * Revision History
0108: * No. Date Who What
0109: * --- ---- --- ----
0110: * 1 2002-04-23 Darshan Added preliminary support for a ClassInfo to
0111: * be constructed from an IClass, to be used
0112: * in model-source operations.
0113: * 2 2002-04-24 Darshan Added more model-source support attributes
0114: * and methods.
0115: * 3 2002-04-24 Darshan Added more tweaks for model-source support -
0116: * ClassInfo now keeps track of the IClass off
0117: * which it was created and can update the IClass
0118: * directly with the file name of the local file
0119: * with which the IClass is associated.
0120: * 4 2002-04-25 Darshan Updated to set the file path to the artifact
0121: * associated with the class and to correctly
0122: * initialize outerClass when creating a ClassInfo
0123: * from an IClass.
0124: * 5 2002-04-29 Darshan Added null checks in updateFilename().
0125: * 6 2002-04-30 Darshan Used JavaClassUtils to map Describe's modifiers
0126: * to Java modifiers.
0127: * 7 2002-04-30 Darshan Reformatted to 4-space tabs, added accessor
0128: * to get the list of interfaces implemented and
0129: * made InterfaceChangeInfo public.
0130: * 8 2002-05-06 Darshan Made removeInterface() check for the same
0131: * interface in the list of added interfaces and
0132: * remove it if already present.
0133: * Reformatted braces to Java style indenting.
0134: * 9 2002-05-13 Darshan Updated to handle both class and interface
0135: * events by manipulating IClassifier references
0136: * instead of directly dealing with IClass and
0137: * IInterface references.
0138: * 10 2002-05-14 Darshan Moved the project selector code from
0139: * update(SymbolTransaction) to update().
0140: * 11 2002-05-28 Darshan Synchronized on EventHandler instance to allow
0141: * synch between source-model and model-source
0142: * threads during class update.
0143: * 12 2002-05-30 Darshan Fixed bugs in addInterface() and
0144: * removeInterface() and added overloaded
0145: * convenience methods for these.
0146: * 13 2002-06-04 Darshan Added code to store only relative paths in a
0147: * class element's artifact. The change is wholly
0148: * internal to ClassInfo, so no other code should
0149: * be affected.
0150: * 14 2002-06-05 Darshan Fixed code to correctly pick up superinterfaces
0151: * of an interface.
0152: * 15 2002-06-10 Darshan Fixed creating multiple generalization links.
0153: * 16 2002-06-14 Darshan Added calls to prevent roundtrip events during
0154: * update.
0155: * 17 2002-06-19 Darshan Flagged interfaces abstract by default.
0156: * 18 2002-06-19 Darshan Added null pointer check before performing
0157: * sanity check :)
0158: * 19 2002-06-20 Darshan Turned on two-way roundtrip for attribute
0159: * updates.
0160: * 20 2002-06-25 Darshan Turned on two-way roundtrip for superclass/
0161: * interface updates (fix for 191 JBuilder- methods
0162: * not passed down to children).
0163: * 21 2002-06-28 Darshan Added support for creating reference classes for
0164: * generalizations if necessary.
0165: * 22 2002-07-02 Mukta Added a method to get the full class name,
0166: * including the package name
0167: * 23 2002-07-24 Darshan Setting the relative path to the file as a
0168: * tagged value on the ISourceFileArtifact
0169: * (temporary workaround as project base dir is
0170: * not set correctly).
0171: * 24 2002-08-14 Mukta Added code to set exisiting methods and
0172: * attributes to the classinfo.
0173: *
0174: * @see EventManager
0175: */
0176: public class ClassInfo extends ElementInfo {
0177: private static final Logger logger = Logger
0178: .getLogger(ClassInfo.class.getName());
0179: /**
0180: * Describe id for class elements.
0181: */
0182: public static final String DS_CLASS = "Class";
0183:
0184: /**
0185: * Describe id for interface elements.
0186: */
0187: public static final String DS_INTERFACE = "Interface";
0188:
0189: /**
0190: * Describe id for enumeration elements.
0191: */
0192: public static final String DS_ENUMERATION = "Enumeration";
0193:
0194: /**
0195: * Describe stereotype id for the interface stereotype.
0196: */
0197: public static final String DS_STE_INTERFACE = "interface";
0198:
0199: /**
0200: * Describe stereotype id for the enumeration stereotype.
0201: */
0202: public static final String DS_STE_ENUMERATION = "enumeration";
0203:
0204: // This is for private use only. I will have to keep track of what items
0205: // have been updated. I do not want to change
0206: //private int mChangesMade = 0;
0207:
0208: private String id = null;
0209: // Darshan: So that SymbolTransaction can find the correct symbol.
0210:
0211: /** The outer class for this class. Only used when a class is an inner
0212: * class. */
0213: private ClassInfo outerClass = null;
0214:
0215: /** The class that is the new super class. */
0216: private String mNewExtendedClass = null;
0217: private IClassifier mSuperClass = null;
0218:
0219: /** The pacakge that contains the new super class. */
0220: private String mNewExtendedPack = null;
0221:
0222: /** The package that contains the old super class. */
0223: private String mRemoveExtendedPack = null;
0224:
0225: /** The class that is longer the super class. */
0226: private String mRemoveExtendedClass = null;
0227:
0228: /** The import of the class. */
0229: private Vector mImports = new Vector();
0230:
0231: /** The class's data memebers. */
0232: private Vector mMembers = new Vector();
0233:
0234: /** The class's methods. */
0235: private Vector mMethods = new Vector();
0236:
0237: /** The class's constructors. */
0238: private Vector mConstructors = new Vector();
0239:
0240: /** The class's inner classes. */
0241: private Vector<ClassInfo> mInnerClasses = new Vector<ClassInfo>();
0242:
0243: /** The class's implemented interfaces. */
0244: private Vector mInterfaces = new Vector();
0245:
0246: // the new/preferred interfaces data member
0247: private ArrayList<IClassifier> super Interfaces = new ArrayList<IClassifier>();
0248:
0249: /** The enumeration's literals. */
0250: private Vector mLiterals = new Vector();
0251:
0252: /** The file that the class lives in. */
0253: private String mFilename = null;
0254:
0255: /** Flag to indicate that this is an inner class. */
0256: private Boolean mIsInnerClass = null;
0257:
0258: /** The class's original package. */
0259: private String mOrigPackage = null;
0260:
0261: /** The class's new package. */
0262: private String mNewPackage = null;
0263:
0264: private EventFilter filter = null;
0265:
0266: /**
0267: * The base path of the project that owns this class. Typically used only
0268: * for model->source updates.
0269: */
0270: private String basePath = null;
0271:
0272: /** Flag to indicate that this class is an interface. */
0273: private boolean mIsInterface = false;
0274:
0275: /** Flag to indicate that this class is an enumeration. */
0276: private boolean mIsEnumeration = false;
0277:
0278: private boolean referenceClass = false;
0279:
0280: private static boolean executingAddin = false;
0281:
0282: private String exportSourceFolderName;
0283:
0284: /**
0285: * The ClassElement which this ClassInfo wraps, usually null when updating
0286: * source to model, non-null otherwise.
0287: */
0288: private IClassifier classElement;
0289:
0290: /**
0291: * Contructs a new ClassInfo object.
0292: * @param type The type of the transaction. Valid values are:
0293: * ElementInfo.CREATE
0294: * ElementInfo.DELETE
0295: * ElementInfo.MODIFY
0296: */
0297: public ClassInfo(int type) {
0298: super (type);
0299: setName("");
0300: setPackage("");
0301: }
0302:
0303: /**
0304: * Creates a ClassInfo with data from the given IClassifier object.
0305: *
0306: * @param clazz
0307: */
0308: public ClassInfo(IClassifier clazz) {
0309: super (clazz);
0310: if (clazz != null) {
0311: eraseRefClass(clazz);
0312: setFromClassifier(clazz);
0313: }
0314: }
0315:
0316: /* (non-Javadoc)
0317: * @see com.embarcadero.integration.events.ElementInfo#getOwningProject()
0318: */
0319: public IProject getOwningProject() {
0320: return classElement != null ? (IProject) classElement
0321: .getProject()
0322: : getOuterClass() != null ? getOuterClass()
0323: .getOwningProject() : null;
0324: }
0325:
0326: /**
0327: * Returns the source directory in which Describe thinks this class should
0328: * live. In general, this is just the value of the SourceDir property for
0329: * the package to which the IClassifier for this class belongs. This method
0330: * will return null if a) the ClassInfo doesn't have an IClassifier b) the
0331: * owning package does not have a valid SourceDir property, or c) a weird
0332: * error occurs. Weird errors are logged, but no exceptions will be thrown.
0333: *
0334: * @return The absolute path in which Describe fancies this file ought to
0335: * live.
0336: */
0337: public String getSourceDirectory() {
0338: if (classElement == null)
0339: return null;
0340: try {
0341: IElement owner = classElement;
0342:
0343: // Retrieve the package in which this class lives. If the class
0344: // is an inner class, we'll want to skip past containing classes.
0345: while ((owner = owner.getOwner()) != null
0346: && !(owner instanceof IPackage))
0347: ;
0348:
0349: if (owner == null) {
0350: // What manner of demonic IClassifier is this anyway?
0351: Log.impossible("Classifier " + classElement.getName()
0352: + " is not in a package?");
0353: return null;
0354: }
0355:
0356: IPackage pack = (IPackage) owner;
0357: return pack.getSourceDir();
0358: } catch (Exception e) {
0359: logger.log(Level.WARNING, null, e);
0360: }
0361: return null;
0362: }
0363:
0364: public String getExportSourcePackage() {
0365: if (classElement == null)
0366: return null;
0367:
0368: try {
0369: IElement owner = classElement;
0370:
0371: // Retrieve the package in which this class lives. If the class
0372: // is an inner class, we'll want to skip past containing classes.
0373: while ((owner = owner.getOwner()) != null
0374: && !(owner instanceof IPackage))
0375: ;
0376:
0377: if (owner == null) {
0378: // What manner of demonic IClassifier is this anyway?
0379: Log.impossible("Classifier " + classElement.getName()
0380: + " is not in a package?");
0381: return null;
0382: }
0383:
0384: String packName = "";
0385: if (!(owner instanceof IProject)) {
0386: IPackage pack = (IPackage) owner;
0387: String fqn = pack.getFullyQualifiedName(false);
0388: if (fqn != null) {
0389: packName = fqn.replace("::", File.separator);
0390: }
0391: }
0392: return createPath(getExportSourceFolderName(), packName);
0393: } catch (Exception e) {
0394: logger.log(Level.WARNING, null, e);
0395: }
0396: return null;
0397: }
0398:
0399: /**
0400: *
0401: * Ensures that an appropriate path is constructed given the source directory and the
0402: * name of this package
0403: *
0404: * @param sourceDir[in] The current source directory
0405: * @param name[in] Name of this package
0406: *
0407: * @return The final source directory
0408: *
0409: */
0410: private String createPath(String sourceDir, String name) {
0411: String path = sourceDir;
0412: if (sourceDir.length() > 0 && name.length() > 0) {
0413: String str = FileSysManip.addBackslash(sourceDir);
0414: str += name;
0415:
0416: // Now we want to support the ability for specific machines to handle
0417: // expansion variables for path expansion specific to that machine
0418: path = FileManip.resolveVariableExpansion(str);
0419: }
0420: return path;
0421: }
0422:
0423: /**
0424: * Retrieves the source directory root that Describe expects the package
0425: * containing this class to live in. This is obtained by retrieving the
0426: * SourceDir property of the owning package/project, and stripping off the
0427: * package directories.
0428: *
0429: * @return The absolute path to the root of the source directory.
0430: */
0431: public String getRootSourceDirectory() {
0432: String sourceDir;
0433:
0434: if (getExportSourceFolderName() != null)
0435: sourceDir = getExportSourceFolderName();
0436:
0437: else
0438: sourceDir = getSourceDirectory();
0439:
0440: if (sourceDir != null) {
0441: // No need to check classElement for null, since it can't be null
0442: // if sourceDir is non-null.
0443: try {
0444: IElement element = classElement;
0445: // Strip off a directory segment for each level of package.
0446: // We don't check to see whether the directory name matches the
0447: // package name, but we probably should, to make sure things
0448: // don't go horribly awry.
0449: while ((element = element.getOwner()) != null
0450: && !(element instanceof IProject))
0451: if (element instanceof IPackage)
0452: sourceDir = new File(sourceDir).getParent();
0453: } catch (Exception e) {
0454: logger.log(Level.WARNING, null, e);
0455: }
0456: }
0457: return sourceDir;
0458: }
0459:
0460: public IProject getProject() {
0461: return classElement != null ? (IProject) classElement
0462: .getProject() : null;
0463: }
0464:
0465: protected void setRefInfo(IClassifier clazz) {
0466: classElement = clazz;
0467:
0468: if (clazz == null)
0469: return;
0470:
0471: String fullname = JavaClassUtils.getFullyQualifiedName(clazz);
0472:
0473: setId(clazz.getXMIID());
0474: setName(JavaClassUtils.getFullInnerClassName(fullname));
0475: setPackage(JavaClassUtils.getPackageName(fullname));
0476:
0477: setIsInterface(clazz instanceof IInterface);
0478: setIsEnumeration(clazz instanceof IEnumeration);
0479:
0480: // If this is an inner class, set the owner
0481: IElement owner = clazz.getOwner();
0482: if (owner instanceof IClassifier) {
0483: IClassifier cp = (IClassifier) owner;
0484: outerClass = getRefClassInfo(cp, true);
0485: /*outerClass = new ClassInfo(null);
0486: outerClass.setRefInfo(cp);
0487: */
0488: }
0489:
0490: updateFilename(null);
0491: }
0492:
0493: /**
0494: * Initializes this ClassInfo using the given Describe IClassifier. Note:
0495: * this is not recommended for use by IDEs.
0496: *
0497: *
0498: * @param cinfo The Describe IClassifier that's used to initialize this
0499: * ClassInfo.
0500: */
0501: public void setFromClassifier(IClassifier classifier) {
0502: if (classifier == null || classifier.getName() == null)
0503: return;
0504:
0505: setRefInfo(classifier);
0506: referenceClass = JavaClassUtils.isReferenceClass(classifier);
0507:
0508: int mods = JavaClassUtils.getJavaModifier(classifier
0509: .getVisibility());
0510:
0511: if (classifier.getIsLeaf())
0512: mods |= Modifier.FINAL;
0513:
0514: if (classifier.getIsAbstract()
0515: && !(classifier instanceof IInterface))
0516: mods |= Modifier.ABSTRACT;
0517:
0518: setModifiers(new Integer(mods));
0519: setSuperInterfaces(classifier);
0520: setSuperclass(classifier);
0521:
0522: if (classifier instanceof IEnumeration)
0523: setLiterals((IEnumeration) classifier);
0524: }
0525:
0526: public void setLiterals(IEnumeration en) {
0527: if (mLiterals == null)
0528: mLiterals = new Vector();
0529:
0530: else
0531: mLiterals.clear();
0532:
0533: for (Iterator iter = en.getLiterals().iterator(); iter
0534: .hasNext();) {
0535: IEnumerationLiteral lit = (IEnumerationLiteral) iter.next();
0536: mLiterals.add(new LiteralInfo(this , lit));
0537: }
0538: }
0539:
0540: public boolean isReferenceClass() {
0541: return referenceClass;
0542: }
0543:
0544: protected IProject getOwningProject(IElement el) {
0545: for (IElement owner = el.getOwner(); owner != null; owner = owner
0546: .getOwner()) {
0547: if (owner instanceof IProject) {
0548: return (IProject) owner;
0549: }
0550: }
0551: return null;
0552: }
0553:
0554: public void setMethodsAndMembers(IClassifier clazz) {
0555: ETList<IOperation> ops = clazz.getOperations();
0556: for (int i = 0; i < ops.getCount(); i++) {
0557: IOperation op = ops.item(i);
0558: addMethod(new MethodInfo(this , op));
0559: }
0560:
0561: ETList<IAttribute> attribs = clazz.getAttributes();
0562: for (int i = 0; i < attribs.getCount(); i++) {
0563: IAttribute attr = attribs.item(i);
0564: addMember(new MemberInfo(this , attr));
0565: }
0566:
0567: // Add attributes for any navigable associations we participate in
0568: ETList<IAssociation> assocs = clazz.getAssociations();
0569: for (int i = 0, count = assocs.size(); i < count; ++i) {
0570: IAssociation assoc = assocs.get(i);
0571: ETList<IAssociationEnd> ends = assoc.getEnds();
0572: if (ends.size() == 2) {
0573: if (ends.get(0) instanceof INavigableEnd) {
0574: INavigableEnd navEnd = (INavigableEnd) ends.get(0);
0575: if (!clazz.isSame(navEnd.getParticipant()))
0576: addMember(new MemberInfo(this , navEnd));
0577: }
0578:
0579: if (ends.get(1) instanceof INavigableEnd) {
0580: INavigableEnd navEnd = (INavigableEnd) ends.get(1);
0581: if (!clazz.isSame(navEnd.getParticipant()))
0582: addMember(new MemberInfo(this , navEnd));
0583: }
0584:
0585: // if both ends have the same participant,
0586: // then we have a self-referencing relationship
0587: if (clazz.isSame(ends.get(0).getParticipant())
0588: && clazz.isSame(ends.get(1).getParticipant())) {
0589: INavigableEnd navEnd = null;
0590:
0591: // if one of the ends is navigable, we need to
0592: // generate an attribute for it
0593:
0594: if (ends.get(0) instanceof INavigableEnd)
0595: navEnd = (INavigableEnd) ends.get(0);
0596:
0597: else if (ends.get(1) instanceof INavigableEnd)
0598: navEnd = (INavigableEnd) ends.get(1);
0599:
0600: if (navEnd != null)
0601: addMember(new MemberInfo(this , navEnd));
0602: }
0603: }
0604: }
0605:
0606: Iterator fs = mMembers.iterator();
0607: while (fs.hasNext()) {
0608: MemberInfo m = (MemberInfo) fs.next();
0609: m.checkGenerateName();
0610: }
0611:
0612: List<INamedElement> owned = clazz.getOwnedElements();
0613: if (owned != null) {
0614: for (INamedElement el : owned) {
0615: if (el instanceof IClass || el instanceof IInterface
0616: || el instanceof IEnumeration) {
0617: ClassInfo cinfo = getRefClassInfo((IClassifier) el,
0618: true, true);
0619: addInnerClass(cinfo);
0620: }
0621: }
0622: }
0623: }
0624:
0625: protected void setSuperclass(IClassifier clazz) {
0626: String super Class = getSuperclass(clazz);
0627:
0628: if (super Class != null) {
0629: if (!(clazz instanceof IEnumeration)) {
0630: setExtendedClass(JavaClassUtils
0631: .getPackageName(super Class), JavaClassUtils
0632: .getFullInnerClassName(super Class));
0633: }
0634:
0635: // In UML, Enumeration elements can't implement Interface elements,
0636: // but they generalize (extend) them, but translation to Java code
0637: // should be "implements" not "extends"
0638: else {
0639: IClassifier genClazz = clazz.getGeneralizations()
0640: .get(0).getGeneral();
0641:
0642: if (genClazz instanceof IInterface)
0643: addSuperInterface(genClazz);
0644: }
0645: }
0646: }
0647:
0648: protected String getSuperclass(IClassifier clazz) {
0649: if (clazz == null || clazz instanceof IInterface
0650: || clazz instanceof IEnumeration) {
0651: return null;
0652: }
0653:
0654: ETList<IGeneralization> gens = clazz.getGeneralizations();
0655:
0656: if (gens != null && gens.getCount() > 0) {
0657: IGeneralization gen = gens.item(0);
0658: IClassifier general;
0659:
0660: if (gen != null && (general = gen.getGeneral()) != null) {
0661: // UML allows a Class element to generalize an Enumeration
0662: // element, but this is not OK in Java, so just ignore it
0663: if (general instanceof IEnumeration)
0664: return null;
0665:
0666: // Class is generalizing one of its inner classes;
0667: // UML allows this, but Java does not
0668: else if (JavaClassUtils.isAnOwner(clazz, general))
0669: return null;
0670:
0671: else {
0672: if (general instanceof IDerivationClassifier) {
0673: IDerivation drv = general.getDerivation();
0674: if (drv != null) {
0675: IClassifier templ = drv.getTemplate();
0676: if (templ instanceof IInterface) {
0677: addSuperInterface(general);
0678: return null;
0679: }
0680: }
0681: }
0682: setSuperClass(general);
0683: String super Class = JavaClassUtils
0684: .getFullyQualifiedName(general);
0685: return super Class;
0686: }
0687: }
0688: }
0689:
0690: return null;
0691: }
0692:
0693: protected void setSuperInterfaces(IClassifier clazz) {
0694: mInterfaces.clear();
0695: super Interfaces.clear();
0696:
0697: if (isInterface()) {
0698: ETList<IGeneralization> gens = clazz.getGeneralizations();
0699:
0700: if (gens != null && gens.getCount() > 0) {
0701: for (int i = 0; i < gens.getCount(); ++i) {
0702: INamedElement interf = gens.item(i).getGeneral();
0703:
0704: if (interf == null)
0705: continue;
0706:
0707: // Interface is implementing one of its inner interfaces;
0708: // UML allows this, but Java does not, so just ignore it
0709: if (JavaClassUtils.isAnOwner(clazz,
0710: (IClassifier) interf)) {
0711: continue;
0712: }
0713:
0714: String fullName = JavaClassUtils
0715: .getFullyQualifiedName(interf);
0716: addInterface(fullName);
0717: super Interfaces.add((IClassifier) interf);
0718: }
0719: }
0720: }
0721:
0722: else {
0723: ETList<IImplementation> impls = clazz.getImplementations();
0724:
0725: if (impls != null && impls.getCount() > 0) {
0726: for (int i = 0; i < impls.getCount(); ++i) {
0727: INamedElement interf = impls.item(i).getSupplier();
0728:
0729: if (interf == null)
0730: continue;
0731:
0732: // Class is implementing one of its inner interfaces;
0733: // UML allows this, but Java does not, so just ignore it
0734: if (JavaClassUtils.isAnOwner(clazz,
0735: (IClassifier) interf)) {
0736: continue;
0737: }
0738:
0739: String fullName = JavaClassUtils
0740: .getFullyQualifiedName(interf);
0741: addInterface(fullName);
0742: super Interfaces.add((IClassifier) interf);
0743: }
0744: }
0745: }
0746: }
0747:
0748: public static void setExecutingAddin(boolean state) {
0749: executingAddin = state;
0750: }
0751:
0752: public static boolean isExecutingAddin() {
0753: return executingAddin;
0754: }
0755:
0756: /**
0757: * Creates a new ClassInfo object.
0758: * @param name The name of the class.
0759: * @param origPackage The package that contained the class before the
0760: * current change.
0761: * @param type The type of the transaction. Valid values are:
0762: * ElementInfo.CREATE
0763: * ElementInfo.DELETE
0764: * ElementInfo.MODIFY
0765: */
0766: public ClassInfo(String name, String origPackage, int type) {
0767: super (type);
0768: setName(name);
0769: setPackage(origPackage);
0770: }
0771:
0772: public ClassInfo(String decoratedName, int type) {
0773: super (type);
0774: setName(JavaClassUtils.getFullInnerClassName(decoratedName));
0775: setPackage(JavaClassUtils.getPackageName(decoratedName));
0776: }
0777:
0778: /**
0779: * Updates the Describe symbol that represents the class.
0780: * @param system The describe system that is to be updated.
0781: */
0782: public void update() {
0783: UMLSupport support = UMLSupport.getUMLSupport();
0784: IProject proj = null; /* NB60TBD UMLSupport.getProjectForPath(getFilename());*/
0785: if (proj != null) {
0786: support.getProjectManager().setCurrentProject(proj);
0787: } else if (UMLSupport.getDefaultProject() != null) {
0788: support.getProjectManager().setCurrentProject(
0789: UMLSupport.getDefaultProject());
0790: Log
0791: .out("THERE is no matching source path for this file location so symbol will be added to the default project");
0792: }
0793:
0794: EventManager manager = EventManager.getEventManager();
0795: //manager.setSystem(system);
0796:
0797: Log.out("=============================================");
0798: Log.out("Update called: " + this );
0799:
0800: //synchronized (gd.getRoundtripQueue()) {
0801: filter = manager.getEventFilter();
0802: filter.blockEvents(this , null);
0803: SymbolTransaction trans = null;
0804: try {
0805: Log.out("Creating SymbolTransaction");
0806: trans = new SymbolTransaction(this );
0807: Log.out("Done creating SymbolTransaction");
0808: } catch (Throwable e) {
0809: ErrorManager.getDefault().notify(e);
0810: } finally {
0811: filter.unblockEvents(this , null);
0812: }
0813:
0814: try {
0815: UMLSupport.setRoundTripEnabled(false);
0816: update(trans);
0817: } finally {
0818: UMLSupport.setRoundTripEnabled(true);
0819: }
0820: //}
0821: }
0822:
0823: public void setId(String id) {
0824: this .id = id;
0825: }
0826:
0827: public String getId() {
0828: return id;
0829: }
0830:
0831: public void setBasePath(String basePath) {
0832: this .basePath = basePath;
0833: }
0834:
0835: public String getBasePath() {
0836: return basePath;
0837: }
0838:
0839: /**
0840: * Set this class's outer class.
0841: * @param outC The outer class definition.
0842: */
0843: public void setOuterClass(ClassInfo outC) {
0844: outerClass = outC;
0845: }
0846:
0847: /**
0848: * Retrieves this class's outer class.
0849: * @return The class information for the outer class, or null if this class
0850: * does not have a outer class.
0851: */
0852: public ClassInfo getOuterClass() {
0853: return outerClass;
0854: }
0855:
0856: // only used by update method
0857: private void checkSanity() {
0858: if (getModifiers() != null) {
0859: int mods = getModifiers().intValue();
0860: if (!Modifier.isAbstract(mods) && isInterface()) {
0861: // Interfaces are always abstract
0862: setModifiers(new Integer(mods | Modifier.ABSTRACT));
0863: }
0864: }
0865:
0866: String oldSuperclass = JavaClassUtils.formFullClassName(
0867: getExtendedPackage(), getExtendedClass()), newSuperclass = JavaClassUtils
0868: .formFullClassName(getRemovedExtendedPackage(),
0869: getRemovedExtendedClass());
0870:
0871: if (oldSuperclass != null
0872: && oldSuperclass.equals(newSuperclass)) {
0873: setExtendedClass(null, null);
0874: setRemovedExtendedClass(null, null);
0875: }
0876: }
0877:
0878: /**
0879: * Update Describe using the specified Symbol transaction.
0880: * @see SymbolTransaction
0881: * @param trans The transaction that represent the Describe symbol to update.
0882: */
0883: public void update(SymbolTransaction trans) {
0884: if (trans.getSymbol() == null) {
0885: Log.out("Transaction has no IClassifier, aborting");
0886: return;
0887: }
0888:
0889: boolean invalidate = false;
0890:
0891: // Sanity checks
0892: checkSanity();
0893:
0894: EventManager manager = EventManager.getEventManager();
0895: filter = manager.getEventFilter();
0896:
0897: try {
0898: //manager.setSystem(system);
0899: IClassifier clazz = trans.getSymbol();
0900: if (clazz == null) {
0901: return;
0902: }
0903:
0904: setId(clazz.getXMIID());
0905:
0906: // // **## Log.out("Updating the class: " + getName());
0907: if (getChangeType() == ElementInfo.DELETE) {
0908: clazz.delete();
0909: return;
0910: } else {
0911: if (getImports() != null) {
0912: updateImports(manager, trans);
0913: }
0914:
0915: if (getFilename() != null) {
0916: ClassInfo.setSymbolFilename(clazz, getFilename());
0917: }
0918:
0919: Log.out("CI: Old package : " + getPackage());
0920: Log.out("CI: Old name : " + getName());
0921: Log
0922: .out("CI: New package : "
0923: + getNewPackage());
0924: Log.out("CI: New name : " + getNewName());
0925: if (getNewPackage() != null
0926: && !getNewPackage().trim().equals("")) {
0927: IPackage pack = SymbolTransaction.getClassPackage(
0928: getNewPackage(), getFilename());
0929: if (getOuterClass() == null) {
0930: pack.addOwnedElement(clazz);
0931: invalidate = true;
0932: }
0933: } else {
0934: if (getNewPackage() != null
0935: && getNewPackage().trim().equals("")) {
0936: if (getOuterClass() == null) {
0937: UMLSupport.getCurrentProject()
0938: .addOwnedElement(clazz);
0939: invalidate = true;
0940: }
0941: }
0942: }
0943:
0944: if (isCommentSet()) {
0945: try {
0946: clazz.setDocumentation(getComment());
0947: } catch (Exception e) {
0948: }
0949: //manager.updateClassComment(trans, getComment());
0950: }
0951:
0952: if (getNewName() != null) {
0953: String newName = getNewName().replace('.', '$');
0954: // inner class name has been changed
0955: if (newName.indexOf("$") > 0) {
0956: newName = newName.substring(newName
0957: .lastIndexOf("$") + 1);
0958: }
0959: if (!clazz.getName().equals(newName)) {
0960: boolean rst = UMLSupport.isRoundTripEnabled();
0961: UMLSupport.setRoundTripEnabled(true);
0962: clazz.setName(newName);
0963: UMLSupport.setRoundTripEnabled(rst);
0964:
0965: if (getNewName().lastIndexOf("$") > 0) { // this is ans inner class
0966: String outerClassName = getNewName()
0967: .substring(
0968: 0,
0969: getNewName().lastIndexOf(
0970: "$"));
0971: if (getPackage() != null
0972: && !getPackage().equals("")) {
0973: outerClassName = getPackage() + "."
0974: + outerClassName;
0975: }
0976: clazz.setOwner(JavaClassUtils
0977: .findClassSymbol(outerClassName));
0978: }
0979: invalidate = true;
0980: }
0981: //manager.updateClassName(trans, utils.getInnerClassName(getNewName()));
0982: }
0983:
0984: if (getModifiers() != null) {
0985: manager.updateClassModifers(trans, getModifiers()
0986: .intValue());
0987: }
0988:
0989: // Update superclass/superinterface data
0990: UMLSupport.setRoundTripEnabled(true);
0991: if (getRemovedExtendedClass() != null) {
0992: // call this method on both super and sub class
0993: //removeGeneralization(suClazz);
0994: filter
0995: .blockEventType(ChangeUtils.RDT_RELATION_DELETED);
0996: filter
0997: .blockEventType(ChangeUtils.RDT_DEPENDENCY_REMOVED);
0998:
0999: Log.out("Blocked Relation Delete events "
1000: + ChangeUtils.RDT_RELATION_DELETED);
1001: try {
1002: removeGeneralization(clazz);
1003: } finally {
1004: filter
1005: .unblockEventType(ChangeUtils.RDT_RELATION_DELETED);
1006: filter
1007: .unblockEventType(ChangeUtils.RDT_DEPENDENCY_REMOVED);
1008: Log.out("UnBlocked Relation Delete events "
1009: + ChangeUtils.RDT_RELATION_DELETED);
1010: }
1011: }
1012:
1013: if (!isEnumeration() && getExtendedClass() != null) {
1014: filter
1015: .blockEventType(ChangeUtils.RDT_RELATION_CREATED);
1016: filter
1017: .blockEventType(ChangeUtils.RDT_DEPENDENCY_ADDED);
1018: Log.out("Blocking Relation Create events "
1019: + ChangeUtils.RDT_RELATION_CREATED);
1020: try {
1021: addGeneralization(clazz);
1022: } finally {
1023: filter
1024: .unblockEventType(ChangeUtils.RDT_RELATION_CREATED);
1025: filter
1026: .unblockEventType(ChangeUtils.RDT_DEPENDENCY_ADDED);
1027: Log.out("UnBlocking Relation Create events "
1028: + ChangeUtils.RDT_RELATION_CREATED);
1029: }
1030: }
1031: try {
1032: filter
1033: .blockEventType(ChangeUtils.RDT_RELATION_DELETED);
1034: filter
1035: .blockEventType(ChangeUtils.RDT_RELATION_CREATED);
1036: filter
1037: .blockEventType(ChangeUtils.RDT_DEPENDENCY_ADDED);
1038: filter
1039: .blockEventType(ChangeUtils.RDT_DEPENDENCY_REMOVED);
1040: updateInterfaces(manager, trans);
1041: } finally {
1042: filter
1043: .unblockEventType(ChangeUtils.RDT_RELATION_DELETED);
1044: filter
1045: .unblockEventType(ChangeUtils.RDT_RELATION_CREATED);
1046: filter
1047: .unblockEventType(ChangeUtils.RDT_DEPENDENCY_ADDED);
1048: filter
1049: .unblockEventType(ChangeUtils.RDT_DEPENDENCY_REMOVED);
1050: }
1051: UMLSupport.setRoundTripEnabled(false);
1052:
1053: try {
1054: UMLSupport.setRoundTripEnabled(false);
1055:
1056: updateMethods(trans, ElementInfo.DELETE);
1057: updateMembers(trans, ElementInfo.DELETE);
1058: if (mIsEnumeration) {
1059: updateEnumLiterals(trans, ElementInfo.DELETE);
1060: }
1061:
1062: updateMethods(trans, ElementInfo.MODIFY);
1063: updateMembers(trans, ElementInfo.MODIFY);
1064: if (mIsEnumeration) {
1065: updateEnumLiterals(trans, ElementInfo.MODIFY);
1066: }
1067:
1068: updateMembers(trans, ElementInfo.CREATE);
1069: updateMethods(trans, ElementInfo.CREATE);
1070: if (mIsEnumeration) {
1071: updateEnumLiterals(trans, ElementInfo.CREATE);
1072: }
1073: } finally {
1074: UMLSupport.setRoundTripEnabled(false);
1075: }
1076: updateConstructors(trans);
1077: }
1078: updateInnerClasses(manager, trans);
1079: manager.setAsInterface(trans, isInterface());
1080: manager.setAsEnumeration(trans, isEnumeration());
1081: } catch (Exception e) {
1082: logger.log(Level.WARNING, null, e);
1083: } finally {
1084: if (invalidate)
1085: eraseRefClass(trans.getSymbol());
1086: }
1087: }
1088:
1089: /**
1090: * Issue a command to Describe to add a generalization associated with a
1091: * class symbol.
1092: * @param state The transaction to act upon.
1093: * @param value The value.
1094: */
1095: public void addGeneralization(IClassifier clazz) {
1096: String super ClassName = null;
1097:
1098: super ClassName = JavaClassUtils.formFullClassName(
1099: getExtendedPackage(), getExtendedClass());
1100:
1101: // Check if the generalization already exists
1102: if (super ClassName.equals(getSuperclass(clazz))) {
1103: // Presumably no further action is required
1104: return;
1105: }
1106:
1107: IClassifier super Clazz = JavaClassUtils
1108: .findClassSymbol(super ClassName);
1109: if (super Clazz == null) {
1110: boolean evt = UMLSupport.isRoundTripEnabled();
1111: UMLSupport.setRoundTripEnabled(false);
1112: try {
1113: super Clazz = JavaClassUtils
1114: .createDataType(JavaClassUtils
1115: .formFullClassName(
1116: getExtendedPackage(),
1117: getExtendedClass()));
1118: /*
1119: superClazz = SymbolTransaction.createClass(getExtendedClass(),
1120: getExtendedPackage(),
1121: false, null,
1122: ElementInfo.CREATE);
1123: // Tag it as a reference class
1124: JavaClassUtils.setReferenceClass(superClazz, true);
1125: */
1126: } finally {
1127: UMLSupport.setRoundTripEnabled(evt);
1128: }
1129: }
1130: IRelationFactory fact = new RelationFactory();
1131: IGeneralization g = fact
1132: .createGeneralization(super Clazz, clazz);
1133: if (g != null) {
1134: IDiagram dia = UMLSupport.getProduct().getDiagramManager()
1135: .getCurrentDiagram();
1136: if (dia != null
1137: && dia.getDiagramKind() == DiagramKind.DK_CLASS_DIAGRAM) {
1138: ICoreRelationshipDiscovery rel = dia
1139: .getRelationshipDiscovery();
1140: if (rel != null)
1141: rel.createPresentationElement(g);
1142: }
1143: }
1144: }
1145:
1146: /**
1147: * Issue a command to Describe to remove a generalization associated with a
1148: * class symbol.
1149: * @param state The transaction to act upon.
1150: * @param value The value.
1151: */
1152: public void removeGeneralization(IClassifier clazz) {
1153: if (clazz == null)
1154: return;
1155: ETList<IGeneralization> rels = clazz.getGeneralizations();
1156: if (rels == null) {
1157: return;
1158: }
1159:
1160: int count = rels.getCount();
1161: for (int i = 0; i < count; i++) {
1162: IGeneralization rel = rels.item(i);
1163: if (rel != null) {
1164: IClassifier gen = rel.getGeneral();
1165: rel.delete();
1166:
1167: if (JavaClassUtils.isReferenceClass(gen)
1168: && JavaClassUtils.isOrphan(gen))
1169: gen.delete();
1170: }
1171: }
1172: }
1173:
1174: /**
1175: * Add an implemented interface to the class definition.
1176: * @param pName The package of the interface.
1177: * @param name The interface name.
1178: */
1179: public void addInterface(String pName, String name) {
1180: if (pName != null && name != null) {
1181: if (!JavaClassUtils.formFullClassName(pName, name).equals(
1182: JavaClassUtils.formFullClassName(getPackage(),
1183: getName()))) {
1184: for (int i = 0; i < mInterfaces.size(); ++i) {
1185: InterfaceChangeInfo ici = (InterfaceChangeInfo) mInterfaces
1186: .elementAt(i);
1187: if (ici.getInterfaceName().equals(name)
1188: && ici.getPackage().equals(pName)) {
1189: ici.setChangeType(ElementInfo.CREATE);
1190: return;
1191: }
1192: }
1193: mInterfaces.add(new InterfaceChangeInfo(pName, name,
1194: ElementInfo.CREATE));
1195: }
1196: }
1197: }
1198:
1199: public void addInterface(String fullname) {
1200: addInterface(JavaClassUtils.getPackageName(fullname),
1201: JavaClassUtils.getFullInnerClassName(fullname));
1202: }
1203:
1204: public InterfaceChangeInfo[] getInterfaces() {
1205: InterfaceChangeInfo[] inf = new InterfaceChangeInfo[mInterfaces
1206: .size()];
1207: mInterfaces.copyInto(inf);
1208: return inf;
1209: }
1210:
1211: /**
1212: * Remove an implemented interface to the class definition.
1213: * @param pName The package of the interface.
1214: * @param name The interface name.
1215: */
1216: public void removeInterface(String pName, String name) {
1217: // First check if we already have an InterfaceChangeInfo with the
1218: // same info, but ADDED
1219: for (int i = 0; i < mInterfaces.size(); ++i) {
1220: InterfaceChangeInfo ici = (InterfaceChangeInfo) mInterfaces
1221: .elementAt(i);
1222: if (ici.getInterfaceName().equals(name)
1223: && ici.getPackage().equals(pName)) {
1224: ici.setChangeType(ElementInfo.DELETE);
1225: return;
1226: }
1227: }
1228: mInterfaces.add(new InterfaceChangeInfo(pName, name,
1229: ElementInfo.DELETE));
1230: }
1231:
1232: public void removeInterface(String fullname) {
1233: removeInterface(JavaClassUtils.getPackageName(fullname),
1234: JavaClassUtils.getFullInnerClassName(fullname));
1235: }
1236:
1237: /**
1238: * Retrieves all the changes to the list of implemented interfaces.
1239: * @return A list of InterfaceChangeInfo.
1240: */
1241: protected Vector getInterfaceChanges() {
1242: return mInterfaces;
1243: }
1244:
1245: /**
1246: * Set the class information that is the super class.
1247: * @param pName The package of the super class.
1248: * @param name The super class name.
1249: * @see #setRemovedExtendedClass
1250: */
1251: public void setExtendedClass(String pName, String name) {
1252: if (pName != null && name != null) {
1253: if (!JavaClassUtils.formFullClassName(pName, name).equals(
1254: JavaClassUtils.formFullClassName(getPackage(),
1255: getName()))) {
1256: mNewExtendedClass = name;
1257: mNewExtendedPack = pName;
1258: }
1259: } else {
1260: //we might be removing them.
1261: mNewExtendedClass = name;
1262: mNewExtendedPack = pName;
1263: }
1264: }
1265:
1266: /**
1267: * Retrieve the name of the super class's.
1268: * @return The name.
1269: * @see #getRemovedExtendedClass
1270: */
1271: public String getExtendedClass() {
1272: return mNewExtendedClass;
1273: }
1274:
1275: /**
1276: * The package that contains the super class.
1277: * @return The package.
1278: * @see #getRemovedExtendedPackage
1279: */
1280: public String getExtendedPackage() {
1281: return mNewExtendedPack;
1282: }
1283:
1284: public String getOldSuperclass() {
1285: return JavaClassUtils.formFullClassName(
1286: getRemovedExtendedPackage(), getRemovedExtendedClass());
1287: }
1288:
1289: public String getNewSuperclass() {
1290: return JavaClassUtils.formFullClassName(getExtendedPackage(),
1291: getExtendedClass());
1292: }
1293:
1294: /**
1295: * Set the class information that is no longer the super class.
1296: * @param pName The package of the super class.
1297: * @param name The super class name.
1298: * @see #setExtendedClass
1299: */
1300: public void setRemovedExtendedClass(String pName, String name) {
1301: mRemoveExtendedClass = name;
1302: mRemoveExtendedPack = pName;
1303: }
1304:
1305: /**
1306: * Retrieve the name of the super class's that is being removed.
1307: * @return The name.
1308: * @see #getExtendedPackage
1309: */
1310: public String getRemovedExtendedPackage() {
1311: return mRemoveExtendedPack;
1312: }
1313:
1314: /**
1315: * Retrieve the name of the super class's that is being removed.
1316: * @return The name.
1317: * @see #getExtendedClass
1318: */
1319: public String getRemovedExtendedClass() {
1320: return mRemoveExtendedClass;
1321: }
1322:
1323: /**
1324: * Set the collection of imports that this class uses.
1325: * @param value A vector of strings.
1326: */
1327: public void setImports(Vector value) {
1328: mImports = value;
1329: }
1330:
1331: /**
1332: * Get the collection of imports that this class uses.
1333: * @return A vector of strings.
1334: */
1335: public Vector getImports() {
1336: return mImports;
1337: }
1338:
1339: /**
1340: * Get the collection of imports that this class uses.
1341: * @return A vector of strings.
1342: */
1343: public void addImport(String stmt) {
1344: stmt = GenCodeUtil.removeGenericType(stmt);
1345:
1346: if (getOuterClass() != null)
1347: getOuterMostOwner().addImport(stmt);
1348:
1349: else if (!mImports.contains(stmt))
1350: mImports.add(stmt);
1351: }
1352:
1353: public void addImport(IClassifier classToImport) {
1354: // is this an inner class? no need to import anything
1355: if (getOuterMostOwner().getClassElement() == getOuterClassifierOwner(classToImport)) {
1356: return;
1357: }
1358:
1359: IPackage owningPackage = classToImport.getOwningPackage();
1360:
1361: // classToImport is in same package as this
1362: if (owningPackage == getClassElement().getOwningPackage())
1363: return;
1364:
1365: // classToImport is owned by (is inner class of) this
1366: else if (owningPackage == getClassElement())
1367: return;
1368:
1369: // classToImport is in the default package (owned by the Project)
1370: else if (owningPackage instanceof org.netbeans.modules.uml.core.metamodel.structure.Project) {
1371: return;
1372: }
1373:
1374: // classToImport is void or primitive type
1375: else if (!GenCodeUtil.isValidClassType(classToImport
1376: .getFullyQualifiedName(false))) {
1377: return;
1378: }
1379:
1380: // classToImport is from the java.lang package
1381: else if (owningPackage.getFullyQualifiedName(false).equals(
1382: "java::lang")) // NOI18N
1383: return;
1384:
1385: // not importing the outer most class for some reason???
1386: IClassifier outerMostClassifier = getOuterClassifierOwner(classToImport);
1387:
1388: addImport(JavaClassUtils.convertUMLtoJava(outerMostClassifier
1389: .getFullyQualifiedName(false)));
1390: }
1391:
1392: private IClassifier getOuterClassifierOwner(IClassifier innerClass) {
1393: IElement owner = innerClass.getOwner();
1394:
1395: if (owner instanceof IPackage || owner instanceof IProject)
1396: return innerClass;
1397:
1398: return getOuterClassifierOwner((IClassifier) owner);
1399: }
1400:
1401: /**
1402: * Sets the class's members that need to be updated. This may not include
1403: * all the class's members, only the ones that need to be updated.
1404: * @param value A list of MemberInfo objects.
1405: */
1406: public void setMembers(Vector value) {
1407: mMembers = value;
1408: }
1409:
1410: /**
1411: * Adds a data member that needs to be updated.
1412: * @param info A list of MemberInfo objects.
1413: */
1414: public void addMember(MemberInfo info) {
1415: mMembers.add(info);
1416: }
1417:
1418: /**
1419: * Gets the class's members that need to be updated. This may not include
1420: * all the class's members, only the ones that need to be updated.
1421: * @return A list of MemberInfo objects.
1422: */
1423: public Vector getMembers() {
1424: return mMembers;
1425: }
1426:
1427: /**
1428: * Sets the class's methods that need to be updated. This may not include
1429: * all the class's method, only the ones that need to be updated.
1430: * @param value A list of MethodInfo objects.
1431: */
1432: public void setMethods(Vector value) {
1433: mMethods = value;
1434: }
1435:
1436: /**
1437: * Adds a method that needs to be updated.
1438: * @param info A list of MethodInfo objects.
1439: */
1440: public void addMethod(MethodInfo info) {
1441: mMethods.add(info);
1442: }
1443:
1444: /**
1445: * Gets the class's methods that need to be updated. This may not include
1446: * all the class's methods, only the ones that need to be updated.
1447: * @return A list of ConstructorInfo objects.
1448: */
1449: public Vector getMethods() {
1450: return mMethods;
1451: }
1452:
1453: /**
1454: * Sets the class's constructors that need to be updated. This may not include
1455: * all the class's constructors, only the ones that need to be updated.
1456: * @param value A list of ConstructorInfo objects.
1457: */
1458: public void setConstructors(Vector value) {
1459: mConstructors = value;
1460: }
1461:
1462: /**
1463: * Adds a constructor to the list of constructors that need to be updated.
1464: *
1465: * @param value The <code>ConstructorInfo</code> to be updated. If this is
1466: * an instance of <code>MethodInfo</code>, <code>addMethod()
1467: * </code> will be called internally (taking advantage of this
1468: * is likely to cause confusion, though).
1469: */
1470: public void addConstructor(ConstructorInfo value) {
1471: if (value instanceof MethodInfo)
1472: // Accommodate stupid callers.
1473: addMethod((MethodInfo) value);
1474: else
1475: mConstructors.add(value);
1476: }
1477:
1478: /**
1479: * Gets the class's constructors that need to be updated. This may not include
1480: * all the class's constructors, only the ones that need to be updated.
1481: * @return A list of MethodInfo objects.
1482: */
1483: public Vector getConstructors() {
1484: return mConstructors;
1485: }
1486:
1487: /**
1488: * Add an inner class that needs to be updated.
1489: * @param info The inner class to add.
1490: */
1491: public void addInnerClass(ClassInfo info) {
1492: info.setOuterClass(this );
1493: if (mInnerClasses != null && !mInnerClasses.contains(info))
1494: mInnerClasses.add(info);
1495: }
1496:
1497: /**
1498: * Sets the class's inner classes that need to be updated. This may not include
1499: * all the class's inner classes, only the ones that need to be updated.
1500: * @param value A list of ClassInfo objects.
1501: */
1502: public void setInnerClasses(Vector value) {
1503: mInnerClasses = value;
1504: }
1505:
1506: /**
1507: * Gets the class's inner classes that need to be updated. This may not include
1508: * all the class's inner classes, only the ones that need to be updated.
1509: * @return A list of ClassInfo objects.
1510: */
1511: public Vector getInnerClasses() {
1512: return mInnerClasses;
1513: }
1514:
1515: /**
1516: * Sets the enumeration's literals that need to be updated. This may not include
1517: * all the enumeration's literals, only the ones that need to be updated.
1518: * @param value A list of LiteralInfo objects.
1519: */
1520: public void setLiterals(Vector value) {
1521: mLiterals = value;
1522: }
1523:
1524: /**
1525: * Adds a enum literal that needs to be updated.
1526: * @param info A list of LiteralInfo objects.
1527: */
1528: public void addLiteral(LiteralInfo info) {
1529: mLiterals.add(info);
1530: }
1531:
1532: /**
1533: * Gets the enumeration's literals that need to be updated. This may not include
1534: * all the enumeration's literals, only the ones that need to be updated.
1535: * @return A list of LiteralInfo objects.
1536: */
1537: public Vector getLiterals() {
1538: return mLiterals;
1539: }
1540:
1541: /**
1542: * Sets the file that that contains the class.
1543: * @param value The name of the file.
1544: */
1545: public void setFilename(String value) {
1546: mFilename = value;
1547: }
1548:
1549: /**
1550: * Updates the IClass associated with this ClassInfo with the
1551: * @param filename
1552: * @return
1553: */
1554: public String updateFilename(String filename) {
1555: if (classElement == null || getChangeType() == DELETE) {
1556: if (filename != null)
1557: setFilename(filename);
1558: return getFilename();
1559: }
1560: if (filename != null) {
1561: setFilename(filename);
1562: Log.out("Updating symbol filename for "
1563: + classElement.getName() + " to " + filename);
1564: setSymbolFilename(classElement, filename);
1565: } else
1566: setFilename(getSymbolFilename(classElement));
1567:
1568: return getFilename();
1569: }
1570:
1571: /**
1572: * Returns the first artifact associated with the given class, or the
1573: * class itself if no artifact is available.
1574: *
1575: * @param clazz
1576: * @return
1577: */
1578: private static ISourceFileArtifact getClassArtifact(
1579: IClassifier clazz) {
1580: ETList<IElement> artifacts = clazz.getSourceFiles();
1581:
1582: if (artifacts == null || artifacts.getCount() == 0)
1583: return null;
1584:
1585: return (ISourceFileArtifact) artifacts.item(0);
1586: }
1587:
1588: /**
1589: * Sets the file with which the given class should be associated.
1590: * Not intended for direct use by IDE integrations.
1591: *
1592: * @param clazz
1593: * @param filename
1594: */
1595: public static void setSymbolFilename(IClassifier clazz,
1596: String filename) {
1597: // Portability FIXME: This code forces the OS-specific directory
1598: // separator, but has the potential to mess up absolute path names in
1599: // OSes where, say, '\' is a valid character in a filename (all Unixen
1600: // enjoy this feature).
1601: if (filename != null)
1602: filename = filename.replace('/', File.separatorChar)
1603: .replace('\\', File.separatorChar);
1604:
1605: ISourceFileArtifact el = getClassArtifact(clazz);
1606: if (el == null) {
1607: if (!(clazz.getOwner() instanceof IClassifier))
1608: clazz.addSourceFile(filename);
1609: } else {
1610: el.setSourceFile(filename);
1611: }
1612: }
1613:
1614: /**
1615: * Gets the file which which the given class is associated. Not intended
1616: * for direct use by IDE integrations.
1617: * @param clazz
1618: * @return
1619: */
1620: public static String getSymbolFilename(IClassifier clazz) {
1621: ISourceFileArtifact el = getClassArtifact(clazz);
1622:
1623: if (el != null)
1624: return el.getSourceFile();
1625: else {
1626: IElement parent = clazz;
1627: while ((parent = parent.getOwner()) instanceof IClassifier) {
1628: IClassifier cparent = (IClassifier) parent;
1629: if ((el = getClassArtifact(cparent)) != null)
1630: return el.getSourceFile();
1631: }
1632: }
1633:
1634: return null;
1635: }
1636:
1637: /**
1638: * Gets the file that that contains the class.
1639: * @return The name of the file.
1640: */
1641: public String getFilename() {
1642: return mFilename;
1643: }
1644:
1645: /**
1646: * Specifies if the ClassInfo represents an inner class or a outer class.
1647: * @param value true if the class is an inner class, false otherwise.
1648: */
1649: public void setIsInnerClass(Boolean value) {
1650: mIsInnerClass = value;
1651: }
1652:
1653: /**
1654: * Retrieves if the ClassInfo represents an inner class or a outer class.
1655: * @return true if the class is an inner class, false otherwise.
1656: */
1657: public Boolean getIsInnerClass() {
1658: return mIsInnerClass;
1659: }
1660:
1661: /**
1662: * Sets the package name that contains the class. This is the original
1663: * package name.
1664: * @param value The fully qualified name of the pacakge.
1665: */
1666: public void setPackage(String value) {
1667: mOrigPackage = value;
1668: }
1669:
1670: /**
1671: * Gets the package name that contains the class. This is the original
1672: * package name.
1673: * @return The fully qualified name of the pacakge.
1674: */
1675: public String getPackage() {
1676: return mOrigPackage;
1677: }
1678:
1679: /**
1680: * Sets the package name that contains the class. This is the new
1681: * package name.
1682: * @param value The fully qualified name of the pacakge.
1683: */
1684: public void setNewPackage(String value) {
1685: mNewPackage = value;
1686: }
1687:
1688: /**
1689: * Gets the package name that contains the class. This is the new
1690: * package name.
1691: * @return The fully qualified name of the pacakge.
1692: */
1693: public String getNewPackage() {
1694: return mNewPackage;
1695: }
1696:
1697: /**
1698: * Specifies if the ClassInfo represents an interface or a class.
1699: * @param value true if the class is an interface, false otherwise.
1700: */
1701: public void setIsInterface(boolean value) {
1702: mIsInterface = value;
1703: }
1704:
1705: /**
1706: * Retrieves if the ClassInfo represents an interface or a class.
1707: * @return true if the class is an interface, false otherwise.
1708: */
1709: public boolean isInterface() {
1710: return mIsInterface;
1711: }
1712:
1713: /**
1714: * Specifies if the ClassInfo represents an enumeration or a class.
1715: * @param value true if the class is an enumeration, false otherwise.
1716: */
1717: public void setIsEnumeration(boolean value) {
1718: mIsEnumeration = value;
1719: }
1720:
1721: /**
1722: * Retrieves if the ClassInfo represents an enumeration or a regular class.
1723: * @return true if the class is an enumeration, false otherwise.
1724: */
1725: public boolean isEnumeration() {
1726: return mIsEnumeration;
1727: }
1728:
1729: /**
1730: * Updates all the methods for this symbol. The methods that will be
1731: * updated are the MethodInfo object that where added to the class info.
1732: * @param trans The transaction that represents the Describe symbol.
1733: * @see SymbolTransaction
1734: */
1735: protected void updateMethods(SymbolTransaction trans, int changeType) {
1736: // **## Log.out("Updating Methods: " + mMethods.size());
1737: for (int i = 0; i < mMethods.size(); i++) {
1738: Log.out("Inside updateMethods ..");
1739: MethodInfo info = (MethodInfo) mMethods.elementAt(i);
1740: if (info.getChangeType() == changeType) {
1741: try {
1742: filter.blockEvents(info, this );
1743: info.update(trans);
1744: } finally {
1745: filter.unblockEvents(info, this );
1746: }
1747: }
1748: }
1749: }
1750:
1751: /**
1752: * Updates all the data members for this symbol. The members that will be
1753: * updated are the MemberInfo object that where added to the class info.
1754: * @param trans The transaction that represents the Describe symbol.
1755: * @see SymbolTransaction
1756: */
1757: protected void updateMembers(SymbolTransaction trans, int changeType) {
1758: // **## Log.out("Updating Members: " + mMembers.size());
1759: for (int i = 0; i < mMembers.size(); i++) {
1760: MemberInfo info = (MemberInfo) mMembers.elementAt(i);
1761: if (info.getChangeType() == changeType) {
1762: try {
1763: filter.blockEvents(info, this );
1764: info.update(trans);
1765: } finally {
1766: filter.unblockEvents(info, this );
1767: }
1768: }
1769: }
1770: }
1771:
1772: /**
1773: * Updates all the data members for this symbol. The members that will be
1774: * updated are the MemberInfo object that where added to the class info.
1775: * @param trans The transaction that represents the Describe symbol.
1776: * @see SymbolTransaction
1777: */
1778: protected void updateEnumLiterals(SymbolTransaction trans,
1779: int changeType) {
1780: for (int i = 0; i < mLiterals.size(); i++) {
1781: LiteralInfo info = (LiteralInfo) mLiterals.elementAt(i);
1782: if (info.getChangeType() == changeType) {
1783: try {
1784: filter.blockEvents(info, this );
1785: info.update(trans);
1786: } finally {
1787: filter.unblockEvents(info, this );
1788: }
1789: }
1790: }
1791: }
1792:
1793: /**
1794: * Updates all the constructors for this symbol. The constructors that will be
1795: * updated are the ConstructorInfo object that where added to the class info.
1796: * @param trans The transaction that represents the Describe symbol.
1797: * @see SymbolTransaction
1798: */
1799: protected void updateConstructors(SymbolTransaction trans) {
1800: // **## Log.out("Updating Constructors: " + mConstructors.size());
1801: for (int i = 0; i < mConstructors.size(); i++) {
1802: ConstructorInfo info = (ConstructorInfo) mConstructors
1803: .elementAt(i);
1804: try {
1805: filter.blockEvents(info, this );
1806: info.update(trans);
1807: } finally {
1808: filter.unblockEvents(info, this );
1809: }
1810: }
1811: }
1812:
1813: /**
1814: * Updates all the inner classes for this symbol. The inner classes that will be
1815: * updated are the ClassInfo object that where added to the class info.
1816: * @param trans The transaction that represents the Describe symbol.
1817: * @see SymbolTransaction
1818: */
1819: protected void updateInnerClasses(EventManager manager,
1820: SymbolTransaction trans) {
1821:
1822: Log
1823: .out("Inside updateInnerClasses ..............................");
1824: Vector innerClasses = getInnerClasses();
1825: Log.out("vector size is " + innerClasses.size());
1826: // **## Log.out("Updating Inner Classes: " + innerClasses.size());
1827: for (int i = 0; i < innerClasses.size(); i++) {
1828: ClassInfo innerClass = (ClassInfo) innerClasses
1829: .elementAt(i);
1830: if (innerClass != null)
1831: Log.out("Updating inner class " + innerClass);
1832: //String fullName = innerClass.getPackage() + "." + innerClass.getName();
1833: SymbolTransaction innerTrans = trans
1834: .getInnerClass(innerClass);
1835: innerClass.update(innerTrans);
1836: }
1837: }
1838:
1839: /**
1840: * Updates all the imports statements for this symbol.
1841: * @param manager The transaction manager.
1842: * @param trans The transaction that represents the Describe symbol.
1843: * @see SymbolTransaction
1844: */
1845: protected void updateImports(EventManager manager,
1846: SymbolTransaction trans) {
1847: // TO DO
1848: }
1849:
1850: /**
1851: * Updates the interfacres that this class implements.
1852: * @param manager The transaction manager.
1853: * @param trans The transaction that represents the Describe symbol.
1854: * @see SymbolTransaction
1855: */
1856: protected void updateInterfaces(EventManager manager,
1857: SymbolTransaction trans) {
1858: Log.out("Inside updateInterfaces ...... ");
1859: Vector iFaces = getInterfaceChanges();
1860: // **## Log.out("Updating Interfaces: " + iFaces.size());
1861:
1862: for (int i = 0; i < iFaces.size(); i++) {
1863: InterfaceChangeInfo info = (InterfaceChangeInfo) iFaces
1864: .elementAt(i);
1865: Log
1866: .out("ClassInfo.updateInterfaces: Interface is "
1867: + info.getPackage() + "."
1868: + info.getInterfaceName());
1869: if (info.getChangeType() == ElementInfo.CREATE)
1870: manager.addInterface(trans, info.getPackage(), info
1871: .getInterfaceName());
1872: else {
1873: Log.out("Removing interface " + info.getPackage() + "."
1874: + info.getInterfaceName());
1875: manager.removeInterface(trans, info.getPackage(), info
1876: .getInterfaceName());
1877: }
1878: }
1879: }
1880:
1881: public String getCode() {
1882: return "C";
1883: }
1884:
1885: /**
1886: * InterfaceChangeInfo is a utility clas that defines interfaces that are
1887: * being implemented are that are that are no longer being removed.
1888: */
1889: public class InterfaceChangeInfo {
1890: private String mName = "";
1891: private String mPackage = "";
1892: private int mChangeType = ElementInfo.CREATE;
1893:
1894: public InterfaceChangeInfo(String pName, String name, int type) {
1895: setInterfaceName(pName, name);
1896: setChangeType(type);
1897: }
1898:
1899: public final String getInterfaceName() {
1900: return mName;
1901: }
1902:
1903: public final String getPackage() {
1904: return mPackage;
1905: }
1906:
1907: public final String getDecoratedName() {
1908: return JavaClassUtils.formFullClassName(mPackage, mName);
1909: }
1910:
1911: public final void setInterfaceName(String pName, String name) {
1912: mPackage = pName;
1913: mName = name;
1914: }
1915:
1916: public final int getChangeType() {
1917: return mChangeType;
1918: }
1919:
1920: public final void setChangeType(int type) {
1921: mChangeType = type;
1922: }
1923: }
1924:
1925: public Object clone() {
1926: ClassInfo ci = (ClassInfo) super .clone();
1927: if (mConstructors != null)
1928: ci.mConstructors = (Vector) mConstructors.clone();
1929: if (mImports != null)
1930: ci.mImports = (Vector) mImports.clone();
1931: if (mMembers != null)
1932: ci.mMembers = (Vector) mMembers.clone();
1933: if (mMethods != null)
1934: ci.mMethods = (Vector) mMethods.clone();
1935: if (mInnerClasses != null)
1936: ci.mInnerClasses = (Vector) mInnerClasses.clone();
1937: if (mInterfaces != null)
1938: ci.mInterfaces = (Vector) mInterfaces.clone();
1939: if (mLiterals != null)
1940: ci.mLiterals = (Vector) mLiterals.clone();
1941: return ci;
1942: }
1943:
1944: /**
1945: * forms a full class name including the package name.
1946: */
1947: public String getFullClassName() {
1948: String pack = this .getPackage();
1949: String className = this .getName();
1950: String rep = className;
1951: if (className != null) {
1952: rep = className.replace('.', '$');
1953: }
1954: return (pack == null || pack.equals("")) ? rep
1955: : (pack + "." + rep);
1956: }
1957:
1958: /**
1959: * Returns the IClassifier from which this ClassInfo was constructed, or
1960: * null if the ClassInfo was not constructed from an IClassifier. Note that
1961: * this is not recommended for use by IDE-specific code.
1962: *
1963: * @return <code>IClassifier</code> The IClassifier from which the ClassInfo
1964: * was built.
1965: */
1966: public IClassifier getClassElement() {
1967: return classElement;
1968: }
1969:
1970: /**
1971: * Looks for the IClassifier corresponding to this ClassInfo in the
1972: * Describe model. The IClassifier found will also be returned by
1973: * subsequent calls to getClassElement().
1974: * Not recommended for use by IDE code.
1975: *
1976: * @return The <code>IClassifier</code>, or null if there is no equivalent
1977: * to this ClassInfo in the Describe model.
1978: */
1979: public IClassifier retrieveClassifier() {
1980: classElement = JavaClassUtils.findClassSymbol(JavaClassUtils
1981: .formFullClassName(getPackage(), getName()));
1982: return classElement;
1983: }
1984:
1985: protected String old2new(String oldS, String newS) {
1986: return (newS != null) ? (oldS + " -> " + newS) : oldS;
1987: }
1988:
1989: public String toString() {
1990: StringBuffer s = new StringBuffer();
1991: s
1992: .append("ClassInfo (" + getFullClassName() + ") ")
1993: .append(getChangeName())
1994: .append("\n")
1995: .append(
1996: " Name : "
1997: + old2new(getName(), getNewName()))
1998: .append("\n")
1999: .append(
2000: " Package : "
2001: + old2new(getPackage(), getNewPackage()))
2002: .append("\n").append(
2003: " Modifiers : "
2004: + getModifierText(getModifiers()))
2005: .append("\n");
2006:
2007: String oldS = getOldSuperclass(), newS = getNewSuperclass();
2008: if (oldS != null || newS != null) {
2009: if (oldS == null)
2010: oldS = "<none>";
2011: if (newS == null)
2012: newS = "<none>";
2013: s.append(" Superclass : " + old2new(oldS, newS));
2014: }
2015:
2016: if ((getMethods() != null && getMethods().size() > 0)
2017: || (getConstructors() != null && getConstructors()
2018: .size() > 0)) {
2019: s.append("\n --- Methods ---\n");
2020: Vector meths = getMethods();
2021: for (int i = 0; i < meths.size(); ++i)
2022: s.append(meths.elementAt(i).toString() + "\n");
2023: Vector cons = getConstructors();
2024: for (int i = 0; i < cons.size(); ++i)
2025: s.append(cons.elementAt(i).toString() + "\n");
2026: }
2027:
2028: if (getMembers() != null && getMembers().size() > 0) {
2029: s.append("\n --- Fields ---\n");
2030: Vector fields = getMembers();
2031: for (Iterator iter = fields.iterator(); iter.hasNext();)
2032: s.append(iter.next().toString() + "\n");
2033: }
2034: return s.toString();
2035: }
2036:
2037: public String getModifierText(Integer mods) {
2038: if (mods == null)
2039: return null;
2040: return Modifier.toString(mods.intValue());
2041: }
2042:
2043: /**
2044: * Determines if the given ElementInfo matches this ClassInfo.
2045: * @see ElementInfo#matches(ElementInfo)
2046: * @param el <code>ElementInfo</code> The ElementInfo to match against.
2047: * @return <code>true</code> if the other ElementInfo is a ClassInfo and
2048: * matches the name, package, JavaDoc comment, superclass, filename
2049: * and modifiers of this ClassInfo.
2050: */
2051: public boolean matches(ElementInfo el) {
2052: if (!(el instanceof ClassInfo))
2053: return false;
2054: ClassInfo other = (ClassInfo) el;
2055: if (getName() != null && !getName().equals(other.getName()))
2056: return false;
2057: if (getPackage() != null
2058: && !getPackage().equals(other.getPackage()))
2059: return false;
2060: if (getComment() != null
2061: && !getComment().equals(other.getComment()))
2062: return false;
2063: if (getExtendedClass() != null
2064: && !getExtendedClass().equals(other.getExtendedClass()))
2065: return false;
2066: if (getExtendedPackage() != null
2067: && !getExtendedPackage().equals(
2068: other.getExtendedPackage()))
2069: return false;
2070: if (getFilename() != null
2071: && !getFilename().equals(other.getFilename()))
2072: return false;
2073: if (getModifiers() != null
2074: && !getModifiers().equals(other.getModifiers()))
2075: return false;
2076: return true;
2077: }
2078:
2079: /**
2080: * Returns a reference ClassInfo, viz. a ClassInfo with the bare minimum
2081: * information needed to locate the source file.
2082: *
2083: * @param c The <code>IClassifier</code> from which to construct the
2084: * <code>ClassInfo</code>. If <code>null</code>, returns
2085: * <code>null</code>.
2086: * @param reuse If <code>true</code>, attempt to reuse a cached ClassInfo
2087: * created from the same IClassifier. Use with care!
2088: * @return The reference <code>ClassInfo</code>.
2089: */
2090: public static ClassInfo getRefClassInfo(IClassifier c, boolean reuse) {
2091: return getRefClassInfo(c, reuse, false);
2092: }
2093:
2094: public static ClassInfo getRefClassInfo(IClassifier c,
2095: boolean reuse, boolean fullInit) {
2096: if (c == null)
2097: return null;
2098:
2099: ClassInfo ci = null;
2100: if (reuse) {
2101: ci = (ClassInfo) refClassInfos.get(c.getXMIID());
2102: //if (ci != null)
2103: // Log.out("Reusing ClassInfo " + ci.getName());
2104: }
2105: if (ci == null) {
2106: if (fullInit) {
2107: ci = new ClassInfo(c);
2108: ci.setMethodsAndMembers(c);
2109: ci.setComment(c.getDocumentation());
2110: } else {
2111: ci = new ClassInfo(null);
2112: ci.setRefInfo(c);
2113: }
2114: if (reuse)
2115: refClassInfos.put(c.getXMIID(), ci);
2116: }
2117:
2118: return ci;
2119: }
2120:
2121: /**
2122: * Clears all cached <code>ClassInfo</code>s created by getRefClassInfo().
2123: */
2124: public static void eraseRefClasses() {
2125: refClassInfos.clear();
2126: }
2127:
2128: /**
2129: * Removes any cached <code>ClassInfo</code> created from the given
2130: * <code>IClassifier</code>.
2131: * @param c The <code>IClassifier</code> which has (probably) been modified,
2132: * thereby invalidating dependent <code>ClassInfo</code>s.
2133: */
2134: public static void eraseRefClass(IClassifier c) {
2135: if (c != null) {
2136: refClassInfos.remove(c.getXMIID());
2137: Log.out("Erased references to " + c.getName());
2138: }
2139: }
2140:
2141: public String getExportSourceFolderName() {
2142: return exportSourceFolderName;
2143: }
2144:
2145: public void setExportSourceFolderName(String sourceFolderName) {
2146: exportSourceFolderName = sourceFolderName;
2147: }
2148:
2149: public FileObject getExportSourceFolderFileObject() {
2150: FileObject fileObj = null;
2151: try {
2152: File file = new File(getExportSourceFolderName());
2153: fileObj = FileUtil.createFolder(file);
2154: } catch (IOException ex) {
2155: logger.log(Level.WARNING, null, ex);
2156: }
2157: return fileObj;
2158: }
2159:
2160: public FileObject getExportPackageFileObject() {
2161: return getExportPackageFileObject(null);
2162: }
2163:
2164: public FileObject getExportPackageFileObject(String subfolder) {
2165: FileObject fileObj = null;
2166: try {
2167: String pathName = getExportSourcePackage();
2168: if (subfolder != null) {
2169: pathName += File.separatorChar + subfolder;
2170: }
2171: File file = new File(pathName);
2172: fileObj = FileUtil.createFolder(file);
2173: } catch (IOException ex) {
2174: logger.log(Level.WARNING, null, ex);
2175: }
2176: return fileObj;
2177: }
2178:
2179: private static Hashtable refClassInfos = new Hashtable();
2180:
2181: public IClassifier getSuperClass() {
2182: return mSuperClass;
2183: }
2184:
2185: public void setSuperClass(IClassifier val) {
2186: this .mSuperClass = val;
2187: }
2188:
2189: public ArrayList<IClassifier> getSuperInterfaces() {
2190: return super Interfaces;
2191: }
2192:
2193: public void setSuperInterfaces(ArrayList<IClassifier> val) {
2194: this .super Interfaces = val;
2195: }
2196:
2197: public void addSuperInterface(IClassifier val) {
2198: if (val != null && !super Interfaces.contains(val)) {
2199: super Interfaces.add(val);
2200: }
2201: }
2202:
2203: public ClassInfo getOuterMostOwner() {
2204: ClassInfo owner = getOuterClass();
2205:
2206: if (owner == null)
2207: return this ;
2208:
2209: return owner.getOuterMostOwner();
2210: }
2211:
2212: //
2213: // added for template codegen
2214: //
2215:
2216: public ClassInfo getSuperClassInfo() {
2217: if (mSuperClass != null) {
2218: return getRefClassInfo(mSuperClass, true);
2219: }
2220: return null;
2221: }
2222:
2223: public ArrayList<ClassInfo> getSuperInterfaceInfos() {
2224: ArrayList<ClassInfo> res = new ArrayList<ClassInfo>();
2225: if (super Interfaces != null) {
2226: for (IClassifier interf : super Interfaces) {
2227: res.add(getRefClassInfo(interf, true));
2228: }
2229: }
2230: return res;
2231: }
2232:
2233: public String[] getFullyQualifiedCodeGenType() {
2234: if (fullyQualifiedName == null) {
2235: IClassifier classType = getClassElement();
2236: if (classType == null) {
2237: return null;
2238: }
2239: IPackage owningPkg = classType.getOwningPackage();
2240: if (owningPkg == null) {
2241: return null;
2242: }
2243: String fullPkgName = owningPkg.getFullyQualifiedName(false);
2244:
2245: // default package elements have the project as the owning package
2246: if (owningPkg instanceof IProject)
2247: fullPkgName = "";
2248:
2249: // get fully qualified name - "com::foo::bar::Outer::Middle::Inner"
2250: String qualName = classType.getFullyQualifiedName(false);
2251: String fullClassName = qualName;
2252:
2253: if (GenCodeUtil.isValidClassType(fullClassName)) {
2254: // extract the full class name - "Outer::Middle::Inner"
2255: // and convert to dot notation = "Outer.Middle.Inner"
2256:
2257: String mask = fullPkgName;
2258: if (classType instanceof ClassifierTemplateParameter) {
2259: IElement parent = classType.getOwner();
2260: if (parent instanceof IClassifier) {
2261: mask = ((IClassifier) parent)
2262: .getFullyQualifiedName(false);
2263: }
2264: }
2265: if (mask != null && mask.length() > 0) {
2266: fullClassName = JavaClassUtils
2267: .convertUMLtoJava(qualName.substring(mask
2268: .length() + 2));
2269: fullPkgName = JavaClassUtils
2270: .convertUMLtoJava(fullPkgName);
2271: }
2272: // it's in the default package
2273: else
2274: fullClassName = JavaClassUtils
2275: .convertUMLtoJava(qualName);
2276:
2277: }
2278: fullyQualifiedName = new String[] { fullPkgName,
2279: fullClassName };
2280: }
2281: return fullyQualifiedName;
2282: }
2283:
2284: private String[] fullyQualifiedName = null;
2285:
2286: public String getShortClassName() {
2287: return JavaClassUtils.getShortClassName(getName());
2288: }
2289:
2290: public String getCodeGenType(boolean fullyQualified,
2291: ClassInfo container) {
2292: if (fullyQualified) {
2293: if (codeGenTypeFullyQualified == null) {
2294: codeGenTypeFullyQualified = GenCodeUtil
2295: .getTypeCodeGenType(getClassElement(),
2296: fullyQualified, container);
2297: }
2298: return codeGenTypeFullyQualified;
2299: } else {
2300: if (codeGenTypeShort == null) {
2301: codeGenTypeShort = GenCodeUtil.getTypeCodeGenType(
2302: getClassElement(), fullyQualified, container);
2303: }
2304: return codeGenTypeShort;
2305: }
2306: }
2307:
2308: private String codeGenTypeFullyQualified = null;
2309: private String codeGenTypeShort = null;
2310:
2311: public Vector getFieldsCodeGenSorted() {
2312: Vector<MemberInfo> res = new Vector<MemberInfo>();
2313: Iterator fs = mMembers.iterator();
2314:
2315: while (fs.hasNext()) {
2316: MemberInfo field = (MemberInfo) fs.next();
2317: res.add(field);
2318: }
2319:
2320: Collections.sort(res, new StaticAndAccessModifierComparator());
2321: return res;
2322: }
2323:
2324: public Vector getConstructorsCodeGenSorted() {
2325: Vector<MethodInfo> res = new Vector<MethodInfo>();
2326: Iterator ms = mMethods.iterator();
2327:
2328: while (ms.hasNext()) {
2329: MethodInfo method = (MethodInfo) ms.next();
2330: IOperation op = method.getOperation();
2331: if (op != null && op.getIsConstructor()) {
2332: res.add(method);
2333: }
2334: }
2335:
2336: Collections.sort(res, new StaticAndAccessModifierComparator());
2337: return res;
2338: }
2339:
2340: public Vector getMethodsCodeGenSorted() {
2341: Vector<MethodInfo> res = new Vector<MethodInfo>();
2342: Iterator ms = mMethods.iterator();
2343:
2344: while (ms.hasNext()) {
2345: MethodInfo method = (MethodInfo) ms.next();
2346: IOperation op = method.getOperation();
2347: if (op != null && (!op.getIsConstructor())) {
2348: res.add(method);
2349: }
2350: }
2351:
2352: Collections.sort(res, new StaticAndAccessModifierComparator());
2353: return res;
2354: }
2355:
2356: public static class StaticAndAccessModifierComparator implements
2357: Comparator<ElementInfo> {
2358:
2359: public int compare(ElementInfo el1, ElementInfo el2) {
2360: int mod1 = el1.getModifiers();
2361: int mod2 = el2.getModifiers();
2362: if (Modifier.isStatic(mod1) == Modifier.isStatic(mod2)) {
2363: int res = compareAccessModifiers(mod1, mod2);
2364: if (res == 0) {
2365: return compareSpecific(el1, el2);
2366: }
2367: return res;
2368: } else if (Modifier.isStatic(mod1))
2369: return -1;
2370: else
2371: // (Modifier.isStatic(mod2))
2372: return 1;
2373: }
2374:
2375: public int compareAccessModifiers(int mod1, int mod2) {
2376: return getNum(mod1) - getNum(mod2);
2377: }
2378:
2379: int getNum(int mod) {
2380: if (Modifier.isPublic(mod))
2381: return 1;
2382: else if (Modifier.isProtected(mod))
2383: return 2;
2384: else if (Modifier.isPrivate(mod))
2385: return 4;
2386: else
2387: //if package
2388: return 3;
2389: }
2390:
2391: /**
2392: * additional checks, ie. for example to have
2393: * setters/getters together, getter first
2394: */
2395: public int compareSpecific(ElementInfo el1, ElementInfo el2) {
2396: if (el1 instanceof MethodInfo && el2 instanceof MethodInfo) {
2397: MethodInfo m1 = (MethodInfo) el1;
2398: MethodInfo m2 = (MethodInfo) el2;
2399: String attr1 = m1.getMemberName();
2400: String attr2 = m2.getMemberName();
2401: if (attr1 != null && attr2 != null) {
2402: int res = attr1.compareTo(attr2);
2403: if (res != 0)
2404: return res;
2405: if (m1.isAccessor())
2406: return -1;
2407: else
2408: return 1;
2409: }
2410: }
2411: // by default we can't say nothing, ie. say that they are equal
2412: return 0;
2413: }
2414: }
2415:
2416: public ArrayList<String> getImportedTypes() {
2417: if (getOuterClass() != null) {
2418: return getOuterClass().getImportedTypes();
2419: }
2420:
2421: // we're the outer class
2422: ArrayList<String> res = new ArrayList<String>();
2423: ArrayList<String[]> refs = getReferredCodeGenTypes();
2424:
2425: Iterator iter = refs.iterator();
2426: while (iter.hasNext()) {
2427: String[] pn = (String[]) iter.next();
2428: if (pn != null && pn.length == 2 && pn[0] != null
2429: && pn[1] != null) {
2430: String pack = pn[0];
2431: String name = pn[1];
2432: if (pack == "")
2433: continue;
2434: if (pack.equals(getPackage())
2435: || pack.equals("java.lang"))
2436: continue;
2437: String fq = pack + "." + name;
2438: res.add(fq);
2439: }
2440: }
2441: Collections.sort(res);
2442: return res;
2443: }
2444:
2445: public ArrayList<ClassInfo> getMemberTypes() {
2446: ArrayList<ClassInfo> res = new ArrayList<ClassInfo>();
2447: for (ClassInfo inner : mInnerClasses) {
2448: res.add(inner);
2449: }
2450: return res;
2451: }
2452:
2453: public ArrayList<String[]> getReferredCodeGenTypes() {
2454: ArrayList<String[]> res = new ArrayList<String[]>();
2455: HashSet<String> fqNames = new HashSet<String>();
2456:
2457: // referred by the fields
2458: if (mMembers != null) {
2459: Iterator fs = mMembers.iterator();
2460: while (fs.hasNext()) {
2461: MemberInfo field = (MemberInfo) fs.next();
2462: ArrayList<String[]> refs = field
2463: .getReferredCodeGenTypes();
2464: GenCodeUtil.mergeReferredCodeGenTypes(res, fqNames,
2465: refs);
2466: }
2467: }
2468:
2469: // referred by the methods' parameters and returns
2470: if (mMethods != null) {
2471: Iterator ms = mMethods.iterator();
2472: while (ms.hasNext()) {
2473: MethodInfo method = (MethodInfo) ms.next();
2474: ArrayList<String[]> refs = method
2475: .getReferredCodeGenTypes();
2476: GenCodeUtil.mergeReferredCodeGenTypes(res, fqNames,
2477: refs);
2478: }
2479: }
2480:
2481: // referred by the inner types
2482: ArrayList<ClassInfo> memberTypes = getMemberTypes();
2483: if (memberTypes != null) {
2484: for (ClassInfo inner : memberTypes) {
2485: ArrayList<String[]> refs = inner
2486: .getReferredCodeGenTypes();
2487: GenCodeUtil.mergeReferredCodeGenTypes(res, fqNames,
2488: refs);
2489: }
2490: }
2491:
2492: // referred by itself - extends/imports
2493: ArrayList<String[]> refs = GenCodeUtil.getReferredCodeGenTypes(
2494: mSuperClass, this );
2495: if (refs != null) {
2496: GenCodeUtil.mergeReferredCodeGenTypes(res, fqNames, refs);
2497: }
2498: if (super Interfaces != null) {
2499: Iterator<IClassifier> sis = super Interfaces.iterator();
2500: while (sis.hasNext()) {
2501: IClassifier si = sis.next();
2502: refs = GenCodeUtil.getReferredCodeGenTypes(si, this );
2503: //refs = GenCodeUtil.getReferredCodeGenTypes(sis.next());
2504: if (refs != null) {
2505: GenCodeUtil.mergeReferredCodeGenTypes(res, fqNames,
2506: refs);
2507: }
2508: }
2509: }
2510:
2511: return res;
2512: }
2513:
2514: // used to check uniquety of attribute names for
2515: // auto generated names
2516: private HashSet<String> attrNames = null;
2517:
2518: boolean checkAddAttributeName(String aName) {
2519: if (attrNames == null) {
2520: attrNames = new HashSet<String>();
2521: Iterator fs = mMembers.iterator();
2522: while (fs.hasNext()) {
2523: MemberInfo m = (MemberInfo) fs.next();
2524: if (m != null) {
2525: String name = m.getName();
2526: if (name != null && !name.trim().equals("")) {
2527: //System.out.println("adding name = "+name);
2528: attrNames.add(name);
2529: }
2530: }
2531: }
2532: }
2533: if (!attrNames.contains(aName)) {
2534: attrNames.add(aName);
2535: return true;
2536: }
2537: return false;
2538: }
2539:
2540: }
|