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.vmd.midp.components;
043:
044: import org.netbeans.api.java.classpath.ClassPath;
045: import org.netbeans.api.java.project.JavaProjectConstants;
046: import org.netbeans.api.java.source.ClasspathInfo;
047: import org.netbeans.api.project.Project;
048: import org.netbeans.api.project.SourceGroup;
049: import org.netbeans.api.project.libraries.Library;
050: import org.netbeans.api.project.libraries.LibraryManager;
051: import org.netbeans.modules.vmd.api.io.DataObjectContext;
052: import org.netbeans.modules.vmd.api.io.ProjectUtils;
053: import org.netbeans.modules.vmd.api.model.Debug;
054: import org.netbeans.modules.vmd.api.model.DesignDocument;
055: import org.netbeans.spi.java.classpath.ClassPathProvider;
056: import org.netbeans.spi.java.project.classpath.ProjectClassPathExtender;
057: import org.openide.filesystems.FileObject;
058: import org.openide.filesystems.FileUtil;
059: import org.openide.loaders.DataObject;
060: import org.openide.util.RequestProcessor;
061: import org.openide.util.Lookup;
062:
063: import java.io.IOException;
064: import java.util.*;
065:
066: /**
067: *
068: * @author Karol Harezlak
069: */
070: public final class MidpProjectSupport {
071:
072: private static final Lookup.Result<ProjectResourceResolver> resolvers = Lookup
073: .getDefault().lookupResult(ProjectResourceResolver.class);
074:
075: /** Creates a new instance of MidpProjectSupport */
076: private MidpProjectSupport() {
077: }
078:
079: public static Collection<? extends ProjectResourceResolver> getAllResolvers() {
080: return resolvers.allInstances();
081: }
082:
083: /**
084: * Add library to the project based on the supplied names
085: * @param document the document
086: * @param libraryNames the library names to be added
087: */
088: public static void addLibraryToProject(
089: final DesignDocument document, final String... libraryNames) {
090: RequestProcessor.getDefault().post(new Runnable() {
091: public void run() {
092: final Project project = getProjectForDocument(document);
093: if (project == null)
094: return;
095: ProjectClassPathExtender extender = project.getLookup()
096: .lookup(ProjectClassPathExtender.class);
097: final LibraryManager libraryManager = LibraryManager
098: .getDefault();
099: for (String libraryName : libraryNames) {
100: final Library library = libraryManager
101: .getLibrary(libraryName);
102: if (library != null) {
103: try {
104: extender.addLibrary(library);
105: } catch (IOException e) {
106: Debug.warning(e);
107: }
108: }
109: }
110: }
111: });
112: }
113:
114: /**
115: * Add library to the project based on the supplied archive files
116: * @param document the document
117: * @param archiveFiles the archive files to be added
118: */
119: public static void addArchiveFileToProject(
120: final DesignDocument document,
121: final FileObject... archiveFiles) {
122: RequestProcessor.getDefault().post(new Runnable() {
123: public void run() {
124: final Project project = getProjectForDocument(document);
125: if (project == null)
126: return;
127: ProjectClassPathExtender extender = project.getLookup()
128: .lookup(ProjectClassPathExtender.class);
129: for (FileObject file : archiveFiles) {
130: if (file == null || !file.isValid())
131: continue;
132: try {
133: extender.addArchiveFile(file);
134: } catch (IOException e) {
135: Debug.warning(e);
136: }
137: }
138: }
139: });
140: }
141:
142: /**
143: * Gets project for document.
144: * @param document the document
145: * @return the project
146: */
147: public static Project getProjectForDocument(DesignDocument document) {
148: if (document == null)
149: return null;
150:
151: DataObjectContext context = ProjectUtils
152: .getDataObjectContextForDocument(document);
153: if (context == null)
154: return null;
155:
156: return ProjectUtils.getProject(context);
157: }
158:
159: /**
160: * Returns a Map keyed by a FileObject matching the relative resource path
161: * while the value is the FileObject representing the classpath root containing
162: * the key FileObject.
163: * @param document the document
164: * @param relativeResourcePath as seen from a MIDlet prespective must start with
165: * @return a map of found file-objects
166: */
167: public static Map<FileObject, FileObject> getFileObjectsForRelativeResourcePath(
168: DesignDocument document, String relativeResourcePath) {
169: assert (document != null);
170: assert (relativeResourcePath != null);
171:
172: if (relativeResourcePath.startsWith("/")) { // NOI18N
173: relativeResourcePath = relativeResourcePath.substring(1);
174: }
175:
176: Map<FileObject, FileObject> matches = new WeakHashMap<FileObject, FileObject>();
177:
178: DataObjectContext context = ProjectUtils
179: .getDataObjectContextForDocument(document);
180: // document is not leaded yet
181: if (context == null) {
182: return Collections.emptyMap();
183: }
184:
185: DataObject dataObject = context.getDataObject();
186:
187: assert (dataObject != null);
188:
189: FileObject primaryFile = dataObject.getPrimaryFile();
190:
191: assert (primaryFile != null);
192:
193: Project project = getProjectForDocument(document);
194: List<ClassPath> classPathList = getClassPath(project,
195: primaryFile);
196:
197: assert (classPathList != null);
198:
199: for (ClassPath cp : classPathList) {
200: FileObject[] roots = cp.getRoots();
201: for (FileObject root : roots) {
202: Enumeration<? extends FileObject> children = root
203: .getChildren(true);
204: while (children.hasMoreElements()) {
205: FileObject child = children.nextElement();
206: String curRelPath = FileUtil.getRelativePath(root,
207: child);
208: if (relativeResourcePath.equals(curRelPath)) {
209: matches.put(child, root);
210: }
211: }
212: }
213: }
214:
215: for (ProjectResourceResolver resolver : resolvers
216: .allInstances()) {
217: Collection<FileObject> collection = resolver
218: .getResourceRoots(project, document
219: .getDocumentInterface().getProjectType());
220: if (collection == null)
221: continue;
222: for (FileObject root : collection) {
223: Enumeration<? extends FileObject> enumeration = root
224: .getChildren(true);
225: while (enumeration.hasMoreElements()) {
226: FileObject object = enumeration.nextElement();
227: String curRelPath = FileUtil.getRelativePath(root,
228: object);
229: if (relativeResourcePath.equals(curRelPath))
230: matches.put(object, root);
231: }
232: }
233: }
234:
235: return matches;
236: }
237:
238: /**
239: * Returns a Map of all images in the project keyed by FileObjects with their relative resource paths as values.
240: * @param document the document
241: * @return the map of found file-objects
242: */
243: public static Map<FileObject, String> getImagesForProject(
244: DesignDocument document, boolean pngOnly) {
245: String EXTENSION_JPEG = "jpeg"; // NOI18N
246: String EXTENSION_JPG = "jpg"; // NOI18N
247: String EXTENSION_GIF = "gif"; // NOI18N
248: String EXTENSION_PNG = "png"; // NOI18N
249:
250: assert (document != null);
251:
252: Map<FileObject, String> imageFileObjects = null;
253: if (pngOnly) {
254: imageFileObjects = getAllFilesForProjectByExt(document,
255: Arrays.asList(EXTENSION_PNG));
256: } else {
257: imageFileObjects = getAllFilesForProjectByExt(document,
258: Arrays.asList(EXTENSION_JPEG, EXTENSION_JPG,
259: EXTENSION_GIF, EXTENSION_PNG));
260: }
261: return imageFileObjects;
262: }
263:
264: /**
265: * Returns a Map of all files matching any of the provided file edxtensions
266: * keyed by FileObjects with their relative resource paths as values.
267: * @param document the document
268: * @return the map of found file-objects
269: */
270: public static Map<FileObject, String> getAllFilesForProjectByExt(
271: DesignDocument document, Collection<String> fileExtensions) {
272: assert (fileExtensions != null);
273: assert (document != null);
274:
275: Map<FileObject, String> matches = new WeakHashMap<FileObject, String>();
276:
277: DataObjectContext context = ProjectUtils
278: .getDataObjectContextForDocument(document);
279: if (context == null) {
280: return Collections.EMPTY_MAP;
281: }
282:
283: DataObject dataObject = context.getDataObject();
284: if (dataObject == null) {
285: return Collections.EMPTY_MAP;
286: }
287:
288: FileObject primaryFile = dataObject.getPrimaryFile();
289: if (primaryFile == null) {
290: return Collections.EMPTY_MAP;
291: }
292:
293: Project project = getProjectForDocument(document);
294: List<ClassPath> classPathList = getClassPath(project,
295: primaryFile);
296: if (classPathList == null) {
297: return Collections.EMPTY_MAP;
298: }
299:
300: for (ClassPath cp : classPathList) {
301: FileObject[] roots = cp.getRoots();
302: for (FileObject root : roots) {
303: //fill the map <FileObject, String relativePath>
304: extractFiles(root, root, matches, fileExtensions);
305: }
306: }
307:
308: for (ProjectResourceResolver resolver : resolvers
309: .allInstances()) {
310: Collection<FileObject> collection = resolver
311: .getResourceRoots(project, document
312: .getDocumentInterface().getProjectType());
313: if (collection == null)
314: continue;
315: for (FileObject root : collection)
316: extractFiles(root, root, matches, fileExtensions);
317: }
318:
319: return matches;
320: }
321:
322: /**
323: * Recurses directories looking for files with given extensions. Case insensitive
324: */
325: private static void extractFiles(FileObject root,
326: FileObject current, final Map<FileObject, String> bank,
327: Collection<String> imgFileExtensions) {
328: if (current.isFolder()) {
329: FileObject[] children = current.getChildren();
330:
331: for (FileObject fo : children) {
332: extractFiles(root, fo, bank, imgFileExtensions);
333: }
334: } else {
335: String currentExt = current.getExt();
336: for (String ext : imgFileExtensions) {
337: if (ext.equalsIgnoreCase(currentExt)) {
338: String relativePath = FileUtil.getRelativePath(
339: root, current);
340: bank.put(current, "/" + relativePath); // NOI18N
341: // System.out.println(current.getPath() + " -> " + "/" + relativePath); // NOI18N
342: }
343: }
344: }
345: }
346:
347: /**
348: * Gets classpath for given project and fileobject.
349: * @param project the project
350: * @param fileObject the file object within the project
351: * @return the list of classpaths
352: */
353: private static List<ClassPath> getClassPath(Project project,
354: FileObject fileObject) {
355: ArrayList<ClassPath> classPathList = new ArrayList<ClassPath>();
356: ClassPathProvider cpp = project.getLookup().lookup(
357: ClassPathProvider.class);
358: //Removed because of low performance
359: //classPathList.add(cpp.findClassPath(fileObject, ClassPath.BOOT));
360: classPathList.add(cpp.findClassPath(fileObject,
361: ClassPath.COMPILE));
362: classPathList.add(cpp.findClassPath(fileObject,
363: ClassPath.SOURCE));
364: return classPathList;
365: }
366:
367: public static ClasspathInfo getClasspathInfo(Project project) {
368: SourceGroup group = getSourceGroup(project);
369: if (group == null)
370: return null;
371: FileObject fileObject = group.getRootFolder();
372: return ClasspathInfo.create(fileObject);
373: }
374:
375: public static SourceGroup getSourceGroup(Project project) {
376: SourceGroup[] sourceGroups = org.netbeans.api.project.ProjectUtils
377: .getSources(project).getSourceGroups(
378: JavaProjectConstants.SOURCES_TYPE_JAVA);
379: if (sourceGroups == null || sourceGroups.length < 1)
380: return null;
381: return sourceGroups[0];
382: }
383:
384: }
|