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: package org.netbeans.modules.uml.core.reverseengineering.reframework;
043:
044: import java.util.Vector;
045:
046: import org.netbeans.modules.uml.common.generics.ETPairT;
047: import org.netbeans.modules.uml.core.metamodel.core.foundation.IElement;
048: import org.netbeans.modules.uml.core.metamodel.core.foundation.INamedElement;
049: import org.netbeans.modules.uml.core.metamodel.structure.IProject;
050: import org.netbeans.modules.uml.core.metamodel.structure.ISourceFileArtifact;
051: import org.netbeans.modules.uml.core.support.umlutils.ETList;
052: import org.netbeans.modules.uml.core.support.umlutils.ElementLocator;
053: import org.netbeans.modules.uml.core.support.umlutils.IElementLocator;
054:
055: public class ProjectClassLocator implements IProjectClassLocator {
056: private IElementLocator m_Locator = null;
057: private Vector<IProject> m_Projects = null;
058:
059: /* (non-Javadoc)
060: * @see org.netbeans.modules.uml.core.reverseengineering.reframework.IProjectClassLocator#addProject(org.netbeans.modules.uml.core.metamodel.structure.IProject)
061: */
062: public void addProject(IProject proj) {
063: if (m_Projects == null) {
064: m_Projects = new Vector<IProject>();
065: }
066: m_Projects.add(proj);
067: }
068:
069: /**
070: * Retreive the loacation the class that contains the speicfied class. The
071: * Describe projects are searched to locate a class with the specified package
072: * can class name.
073: *
074: * @param package [in] The package that contains the calling class.
075: * @param className [in] The name of the class to locate.
076: * @param fullpath [out] The name of the file that contains the class defintion.
077: * If the class is not located fullpath wil be an
078: * empty string.
079: * @return S_OK if no errors ocured. DSL_E_INIT_SYSTEM if the system has not
080: * been initialized, and E_INVALID_ARG if className is an empty string.
081: */
082: public ETPairT<String, String> locateFileForClass(String pack,
083: String className, ETList<IDependencyEvent> deps) {
084: ETPairT<String, String> retVal = null;
085: IElementLocator pLocator = getElementLocator();
086: if (pLocator != null && m_Projects != null) {
087: int count = m_Projects.size();
088: for (int i = 0; i < count; i++) {
089: IProject proj = m_Projects.get(i);
090:
091: if (pack != null && (pack.length() > 0)
092: && (className.indexOf("::") == -1)) {
093: className = pack + "::" + className;
094: }
095:
096: ETList<IElement> foundElems = pLocator
097: .findScopedElements(proj, className);
098: if (foundElems != null) {
099: int size = foundElems.size();
100: for (int j = 0; j < size; j++) {
101: IElement curEle = foundElems.get(j);
102: if (curEle instanceof INamedElement) {
103: INamedElement neEle = (INamedElement) curEle;
104: retVal = findClass(neEle, className, pack,
105: deps);
106: if (retVal != null) {
107: break;
108: }
109: }
110: }
111: }
112: }
113: }
114: return retVal;
115: }
116:
117: /**
118: * Checks if an INamedElement is the model elemetn that we are looking for,
119: *
120: * Search Algorithm:
121: * 1) Check if the elements qualified name is the same as the passed in
122: * class name.
123: * 2) Check if the passed in name is in the same package as the passed
124: * in package name.
125: * 3) Check if the passed in element is specified in the dependencies.
126: *
127: * @param pElement [in] The element to test.
128: * @param className [in] The name of the class to find.
129: * @param package [in] The package that contains the eferencing ("this") class.
130: * @param depends [in] The dependencies of the referencing ("this") class.
131: * @param fullScopeName [out] The fully qualified name of the located class.
132: * <B>NOTE:</B> fullScopeName will only be set if
133: * the return value is S_OK.
134: * @param fullPath [out] The path to the file that contains the class.
135: * <B>NOTE:</B> fullPath will only be set if
136: * the return value is S_OK.
137: *
138: * @return S_OK if the class was located; S_FALSE if the class was not located.
139: */
140: public ETPairT<String, String> findClass(INamedElement pElement,
141: String className, String pack, ETList<IDependencyEvent> deps) {
142: ETPairT<String, String> retVal = null;
143:
144: String qualName = pElement.getFullyQualifiedName(false);
145: String classStr = className;
146: String fullScopeName = "";
147: String fullPath = getSourceIfSame(pElement, classStr, qualName);
148: if (pack != null && pack.length() > 0 && fullPath == null) {
149: String cPack = pack;
150: cPack += "::";
151: cPack += className;
152: fullPath = getSourceIfSame(pElement, cPack, qualName);
153: if (fullPath != null) {
154: fullScopeName = cPack;
155: }
156: } else {
157: fullScopeName = qualName;
158: }
159:
160: if (fullPath == null) {
161: retVal = findUsingDependencies(pElement, qualName,
162: className, deps, fullScopeName);
163: } else {
164: retVal = new ETPairT<String, String>(fullScopeName,
165: fullPath);
166: }
167:
168: return retVal;
169: }
170:
171: /**
172: * Searchs the dependencies to determine if the specified qualified name is
173: * the is the desiried class.
174: *
175: * @param pElement [in] The element to test.
176: * @param qualName [in] The qualified name of the class to find.
177: * @param className [in] The name of the class to find. The class name is used if
178: * a dependency is a package dependency as opposed to a class
179: * dependency.
180: * @param package [in] The package that contains the eferencing ("this") class.
181: * @param depends [in] The dependencies of the referencing ("this") class.
182: * @param fullScopeName [out] The fully qualified name of the located class.
183: * <B>NOTE:</B> fullScopeName will only be set if
184: * the return value is S_OK.
185: * @param fullPath [out] The path to the file that contains the class.
186: * <B>NOTE:</B> fullPath will only be set if
187: * the return value is S_OK.
188: *
189: * @return S_OK if the class was located; S_FALSE if the class was not located.
190: */
191: public ETPairT<String, String> findUsingDependencies(
192: INamedElement pElement, String qualName, String className,
193: ETList<IDependencyEvent> deps, String fullScopeName) {
194: ETPairT<String, String> retVal = null;
195: String fullPath = "";
196: if (deps != null) {
197: int count = deps.size();
198: for (int i = 0; i < count; i++) {
199: IDependencyEvent depEvent = deps.get(i);
200: String depPack = depEvent.getSupplier();
201: if (depPack != null && depPack.length() > 0) {
202: // If the dependency is a class dependecy and it is the
203: // class that we are looking for then use that dependency;
204: boolean isClassDep = depEvent
205: .getIsClassDependency();
206: if (isClassDep) {
207: boolean isSame = depEvent
208: .isSameClass(className);
209: if (isSame) {
210: fullPath = getSourceIfSame(pElement,
211: depPack, qualName);
212: if (fullPath != null) {
213: fullScopeName = depPack;
214: }
215: break;
216: }
217: } else {
218: depPack += "::";
219: depPack += className;
220:
221: fullPath = getSourceIfSame(pElement, depPack,
222: qualName);
223:
224: if (fullPath != null) {
225: fullScopeName = depPack;
226: }
227: break;
228: }
229: }
230: }
231: }
232: return retVal;
233: }
234:
235: public String getSourceIfSame(INamedElement pElement,
236: String dependencyPackage, String qualName) {
237: String fullPath = null;
238: if (dependencyPackage != null
239: && dependencyPackage.equals(qualName)) {
240: fullPath = getSourceLocation(pElement);
241: }
242: return fullPath;
243: }
244:
245: public String getSourceLocation(IElement pElement) {
246: String retVal = null;
247: if (pElement != null) {
248: ETList<IElement> pArtifacts = pElement.getSourceFiles();
249: if (pArtifacts != null) {
250: int count = pArtifacts.size();
251: if (count > 0) {
252: IElement pEle = pArtifacts.get(0);
253: if (pEle instanceof ISourceFileArtifact) {
254: retVal = ((ISourceFileArtifact) pEle)
255: .getSourceFile();
256: }
257: }
258: }
259: }
260: return retVal;
261: }
262:
263: /**
264: * Retrieve the full path to the specified class name.
265: *
266: * @param filename [in] The short form of the file name.
267: * @param fullpath [out] The full path to the specified file.
268: * If the class is not located fullpath wil be an
269: * empty string.
270: */
271: public String locateFile(String filename) {
272: //nothing in C++ code.
273: return null;
274: }
275:
276: /**
277: * Only valid way to access m_cpElementLocator.
278: * Ensures m_cpElementLocator is valid and returns it as a reference
279: */
280: private IElementLocator getElementLocator() {
281: if (m_Locator == null) {
282: m_Locator = new ElementLocator();
283: }
284: return m_Locator;
285: }
286: }
|