001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.apisupport.project.queries;
043:
044: import java.io.File;
045: import java.io.IOException;
046: import java.util.Collections;
047: import java.util.HashSet;
048: import java.util.Set;
049: import javax.swing.event.ChangeListener;
050: import org.netbeans.api.project.FileOwnerQuery;
051: import org.netbeans.api.project.Project;
052: import org.netbeans.api.project.ProjectManager;
053: import org.netbeans.api.project.ant.AntArtifact;
054: import org.netbeans.api.project.ant.AntArtifactQuery;
055: import org.netbeans.modules.apisupport.project.NbModuleProject;
056: import org.netbeans.modules.apisupport.project.NbModuleProjectType;
057: import org.netbeans.modules.apisupport.project.Util;
058: import org.netbeans.modules.apisupport.project.universe.ModuleEntry;
059: import org.netbeans.modules.apisupport.project.universe.ModuleList;
060: import org.netbeans.spi.project.SubprojectProvider;
061: import org.netbeans.spi.project.support.ant.PropertyUtils;
062: import org.openide.ErrorManager;
063: import org.openide.filesystems.FileObject;
064: import org.openide.filesystems.FileUtil;
065: import org.w3c.dom.Element;
066:
067: /**
068: * Enumerates subprojects, defined as other modules on which this one
069: * has build-time dependencies.
070: * @author Jesse Glick
071: */
072: public final class SubprojectProviderImpl implements SubprojectProvider {
073:
074: private final NbModuleProject project;
075:
076: public SubprojectProviderImpl(NbModuleProject project) {
077: this .project = project;
078: }
079:
080: public Set<? extends Project> getSubprojects() {
081: // XXX could use a special set w/ lazy isEmpty() - cf. #58639 for freeform
082: Set<Project> s = new HashSet<Project>();
083: ModuleList ml;
084: try {
085: ml = project.getModuleList();
086: } catch (IOException e) {
087: Util.err.notify(ErrorManager.INFORMATIONAL, e);
088: return Collections.emptySet();
089: }
090: Element data = project.getPrimaryConfigurationData();
091: Element moduleDependencies = Util.findElement(data,
092: "module-dependencies",
093: NbModuleProjectType.NAMESPACE_SHARED); // NOI18N
094: assert moduleDependencies != null : "Malformed metadata in "
095: + project;
096: for (Element dep : Util.findSubElements(moduleDependencies)) {
097: /* Probably better to open runtime deps too. TBD.
098: if (Util.findElement(dep, "build-prerequisite", // NOI18N
099: NbModuleProjectType.NAMESPACE_SHARED) == null) {
100: continue;
101: }
102: */
103: Element cnbEl = Util.findElement(dep, "code-name-base", // NOI18N
104: NbModuleProjectType.NAMESPACE_SHARED);
105: String cnb = Util.findText(cnbEl);
106: ModuleEntry module = ml.getEntry(cnb);
107: if (module == null) {
108: Util.err.log(ErrorManager.WARNING,
109: "Warning - could not find dependent module "
110: + cnb + " for " + project);
111: continue;
112: }
113: File moduleProjectDirF = module.getSourceLocation();
114: if (moduleProjectDirF == null) {
115: Util.err.log(ErrorManager.WARNING,
116: "Warning - could not find sources for dependent module "
117: + cnb + " for " + project);
118: continue;
119: }
120: FileObject moduleProjectDir = FileUtil
121: .toFileObject(moduleProjectDirF);
122: if (moduleProjectDir == null) {
123: Util.err.log(ErrorManager.WARNING,
124: "Warning - could not load sources for dependent module "
125: + cnb + " for " + project);
126: continue;
127: }
128: try {
129: Project moduleProject = ProjectManager.getDefault()
130: .findProject(moduleProjectDir);
131: if (moduleProject == null) {
132: Util.err.log(ErrorManager.WARNING,
133: "Warning - dependent module " + cnb
134: + " for " + project
135: + " is not projectized");
136: continue;
137: }
138: s.add(moduleProject);
139: } catch (IOException e) {
140: Util.err.notify(e);
141: }
142: }
143: // #63824: consider also artifacts found in ${cp.extra} and/or <class-path-extension>s
144: for (Element cpext : Util.findSubElements(data)) {
145: if (!cpext.getTagName().equals("class-path-extension")) { // NOI18N
146: continue;
147: }
148: Element binorig = Util.findElement(cpext, "binary-origin",
149: NbModuleProjectType.NAMESPACE_SHARED); // NOI18N
150: if (binorig == null) {
151: continue;
152: }
153: String text = Util.findText(binorig);
154: String eval = project.evaluator().evaluate(text);
155: if (eval == null) {
156: continue;
157: }
158: File jar = project.getHelper().resolveFile(eval);
159: AntArtifact aa = AntArtifactQuery.findArtifactFromFile(jar);
160: if (aa != null) {
161: Project owner = aa.getProject();
162: if (owner != null) {
163: s.add(owner);
164: }
165: }
166: }
167: String eval = project.evaluator().getProperty("cp.extra"); // NOI18N
168: if (eval != null) {
169: String[] pieces = PropertyUtils.tokenizePath(eval);
170: for (int i = 0; i < pieces.length; i++) {
171: File jar = project.getHelper().resolveFile(pieces[i]);
172: Project owner = FileOwnerQuery.getOwner(jar.toURI());
173: if (owner != null) {
174: s.add(owner);
175: }
176: }
177: }
178: return s;
179: }
180:
181: public void addChangeListener(ChangeListener listener) {
182: // XXX no impl yet
183: }
184:
185: public void removeChangeListener(ChangeListener listener) {
186: // XXX
187: }
188:
189: }
|