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.projectimport.j2seimport;
043:
044: import java.io.File;
045: import java.util.ArrayList;
046: import java.util.Collection;
047: import java.util.HashSet;
048: import java.util.Iterator;
049: import java.util.LinkedHashSet;
050: import java.util.Set;
051: import java.util.logging.Logger;
052: import org.openide.filesystems.FileObject;
053: import org.openide.filesystems.FileUtil;
054: import org.openide.util.NbBundle;
055:
056: /**
057: *
058: * @author Radek Matous
059: */
060: public final class AbstractProject implements ProjectModel {
061: private final Collection libraries;
062: private final Collection userLibraries;
063: private final Collection sourceRoots;
064: private final Set dependencies;
065: private File jdkDirectory;
066: private String jdkId;
067: private final FileObject projectDir;
068: private final String name;
069: private WarningContainer warnings;
070:
071: private boolean isAlreadyImported = false;
072:
073: public static final Logger logger = LoggerFactory.getDefault()
074: .createLogger(AbstractProject.class);
075:
076: /** Creates a new instance of AbstractProjectDefinition */
077: public AbstractProject(String name, FileObject projectDir) {
078: this .projectDir = projectDir;
079: this .name = name;
080: if (name.indexOf('/') != -1) {
081: throw new IllegalArgumentException();
082: }
083:
084: libraries = new LinkedHashSet();
085: userLibraries = new LinkedHashSet();
086: sourceRoots = new LinkedHashSet();
087: dependencies = new LinkedHashSet();
088: warnings = new WarningContainer();
089:
090: logger.finest("created project: " + "\"" + name + "\" (" + //NOI18N
091: projectDir.getPath() + ")");//NOI18N
092:
093: }
094:
095: public String getName() {
096: return name;
097: }
098:
099: public FileObject getProjectDir() {
100: return projectDir;
101: }
102:
103: public boolean isAlreadyImported() {
104: return isAlreadyImported;
105: }
106:
107: public void setAsImported() {
108: isAlreadyImported = true;
109: }
110:
111: public Collection/*<AbstractProjectDefinition.AbstractLibraryEntry>*/getLibraries() {
112: return libraries;
113: }
114:
115: private void addWarning(final String warning,
116: boolean userNotification) {
117: StringBuffer sbuf = new StringBuffer(NbBundle.getMessage(
118: AbstractProject.class, "MSG_ProjectDefinitionWarning"));//NOI18N
119: sbuf.append(" ").append(warning);//NOI18N
120:
121: String warningPlusPrefix = sbuf.toString();
122: warnings.add(warningPlusPrefix, userNotification);
123: AbstractProject.logger.warning(warningPlusPrefix);
124: }
125:
126: public boolean addLibrary(final AbstractProject.Library lEntry) {
127: if (isAlreadyImported()) {
128: throw new IllegalStateException(
129: "Unexpected usage: project was already imported");//NOI18N
130: }
131:
132: if (!lEntry.isValid()) {
133: addWarning(NbBundle.getMessage(AbstractProject.class,
134: "MSG_InvalidLibrary", lEntry.getArchiv()
135: .getAbsolutePath(), this .getName()), false);//NOI18N
136: }
137:
138: boolean retVal = libraries.add(lEntry);
139: if (retVal == false) {
140: addWarning(NbBundle.getMessage(AbstractProject.class,
141: "MSG_AlreadyExistsLibrary", lEntry.getArchiv()
142: .getAbsolutePath(), this .getName()), false); //NOI18N
143: }
144:
145: logger.finest("added library: " + "\""
146: + lEntry.getArchiv().getAbsolutePath() + "\""); //NOI18N
147:
148: return retVal;
149: }
150:
151: public Collection/*<AbstractProjectDefinition.AbstractUserLibrary>*/getUserLibraries() {
152: return userLibraries;
153: }
154:
155: public boolean addUserLibrary(
156: final AbstractProject.UserLibrary uEntry) {
157: if (isAlreadyImported()) {
158: throw new IllegalStateException(
159: "Unexpected usage: project was already imported");//NOI18N
160: }
161:
162: if (!uEntry.isValid()) {
163: addWarning(NbBundle.getMessage(AbstractProject.class,
164: "MSG_InvalidUserLibrary", uEntry.getName(), this
165: .getName()), true); //NOI18N
166: }
167:
168: checkUserLibrary(uEntry);
169: boolean retVal = userLibraries.add(uEntry);
170:
171: if (retVal == false) {
172: addWarning(NbBundle.getMessage(AbstractProject.class,
173: "MSG_AlreadyExistsUserLibrary", uEntry.getName(),
174: this .getName()), false); //NOI18N
175: }
176:
177: logger.finest("added user library: " + "\"" + uEntry.getName()
178: + "\""); //NOI18N
179:
180: return retVal;
181: }
182:
183: private void checkUserLibrary(AbstractProject.UserLibrary uLibrary) {
184: for (Iterator it = uLibrary.getLibraries().iterator(); it
185: .hasNext();) {
186: AbstractProject.Library lEntry = (AbstractProject.Library) it
187: .next();
188: if (getLibraries().contains(lEntry)) {
189: addWarning(NbBundle.getMessage(AbstractProject.class,
190: "MSG_AlreadyExistsLibrary", lEntry.getArchiv()
191: .getAbsolutePath(), this .getName()),
192: false); //NOI18N
193: }
194: }
195: }
196:
197: public Collection/*<AbstractProjectDefinition.AbstractSourceRootEntry>*/getSourceRoots() {
198: return sourceRoots;
199: }
200:
201: public boolean addSourceRoot(
202: final AbstractProject.SourceRoot srcEntry) {
203: if (isAlreadyImported()) {
204: throw new IllegalStateException(
205: "Unexpected usage: project was already imported");//NOI18N
206: }
207:
208: if (!srcEntry.isValid()) {
209: addWarning(NbBundle.getMessage(AbstractProject.class,
210: "MSG_InvalidSourceRoot", srcEntry.getDirectory()
211: .getAbsolutePath(), this .getName()), false); //NOI18N
212: return false;
213: }
214:
215: boolean retVal = sourceRoots.add(srcEntry);
216: if (retVal == false) {
217: addWarning(NbBundle.getMessage(AbstractProject.class,
218: "MSG_AlreadyExistsSourceRoot", srcEntry
219: .getDirectory().getAbsolutePath(), this
220: .getName()), false); //NOI18N
221: }
222:
223: logger.finest("added source root: " + "\""
224: + srcEntry.getLabel() + " ("
225: + srcEntry.getDirectory().getAbsolutePath() + ")\""); //NOI18N
226:
227: return retVal;
228: }
229:
230: public java.util.Set/*<AbstractProjectDefinition>*/getDependencies() {
231: return dependencies;
232: }
233:
234: public boolean addDependency(final AbstractProject projectDefinition) {
235: if (isAlreadyImported()) {
236: throw new IllegalStateException(
237: "Unexpected usage: project was already imported");//NOI18N
238: }
239:
240: logger.finest("added dependency: " + "\""
241: + projectDefinition.getName() + "\" (" + //NOI18N
242: projectDefinition.getProjectDir().getPath() + ")");//NOI18N
243:
244: return dependencies.add(projectDefinition);
245: }
246:
247: public File getJDKDirectory() {
248: return jdkDirectory;
249: }
250:
251: public void setJDKDirectory(File jdkDirectory) {
252: this .jdkDirectory = jdkDirectory;
253: }
254:
255: public void setInvalidJDK(String expectedJDKId) {
256: addWarning(NbBundle.getMessage(AbstractProject.class,
257: "MSG_JDKDoesnExistUseDefault", this .getName(),
258: expectedJDKId), true); //NOI18N
259: }
260:
261: public WarningContainer getWarnings() {
262: return warnings;
263: }
264:
265: public Collection/**<String>*/
266: getErrors() {
267: Collection errors = new HashSet();
268: DependencyValidator instance = DependencyValidator
269: .checkProject(this );
270: if (!instance.isValid()) {
271: errors.add(instance.getErrorMessage());
272: }
273: if (getSourceRoots().size() == 0) {
274: errors.add(NbBundle.getMessage(AbstractProject.class,
275: "ERR_NoSourceRoot", this .getName()));//NOI18N
276:
277: }
278: return errors;
279: }
280:
281: public static final class SourceRoot implements
282: ProjectModel.SourceRoot {
283: private final String label;
284: private final File sourceFolder;
285:
286: public SourceRoot(String label, File sourceFolder) {
287: this .label = label;
288: this .sourceFolder = sourceFolder;
289: }
290:
291: public final String getLabel() {
292: return label;
293: }
294:
295: public final File getDirectory() {
296: return sourceFolder;
297: }
298:
299: public final boolean isValid() {
300: return AbstractProject.isValid(getDirectory());
301: }
302:
303: public boolean equals(Object obj) {
304: return (obj instanceof SourceRoot) ? ((SourceRoot) obj)
305: .getDirectory().equals(getDirectory()) : false;
306: }
307:
308: public int hashCode() {
309: return getLabel().hashCode();
310: }
311:
312: public String toString() {
313: StringBuffer sb = new StringBuffer();
314: sb.append(NbBundle.getMessage(AbstractProject.class,
315: "TXT_SourceRoot"));//NOI18N
316: sb.append((isValid()) ? "" : "!");//NOI18N
317: sb.append((sourceFolder != null) ? sourceFolder
318: .getAbsolutePath() : "");//NOI18N
319:
320: return sb.toString();
321: }
322:
323: }
324:
325: public static final class Library implements ProjectModel.Library {
326: private File archiv;
327:
328: public Library(File archiv) {
329: this .archiv = archiv;
330: }
331:
332: public java.io.File getArchiv() {
333: return archiv;
334: }
335:
336: public final boolean isValid() {
337: return AbstractProject.isValidArchiv(getArchiv());
338: }
339:
340: public boolean equals(Object obj) {
341: return (obj instanceof Library) ? ((Library) obj)
342: .getArchiv().equals(getArchiv()) : false;
343: }
344:
345: public String toString() {
346: StringBuffer sb = new StringBuffer();
347: sb.append(NbBundle.getMessage(AbstractProject.class,
348: "TXT_Library"));//NOI18N
349: sb.append((isValid()) ? "" : "!");//NOI18N
350: sb.append((archiv != null) ? archiv.getAbsolutePath() : "");//NOI18N
351:
352: return sb.toString();
353: }
354: }
355:
356: public static final class UserLibrary implements
357: ProjectModel.UserLibrary {
358: private final String name;
359: private Collection/*<AbstractProject.Library>*/libraries;
360: private boolean fileNotFound = false;
361: private Collection/*<AbstractProject.UserLibrary>*/dependencies;
362:
363: public UserLibrary(String name, boolean fileNotFound) {
364: this (name);
365: this .fileNotFound = fileNotFound;
366: }
367:
368: public UserLibrary(String name) {
369: this .name = name;
370: libraries = new HashSet();
371: dependencies = new HashSet();
372: }
373:
374: public UserLibrary(String name,
375: Collection/*<AbstractLibraryEntry>*/libraries) {
376: this (name);
377: libraries.addAll(libraries);
378: }
379:
380: public boolean addLibrary(ProjectModel.Library lEntry) {
381: logger.finest("added library: " + "\""
382: + lEntry.getArchiv().getAbsolutePath() + "\""); //NOI18N
383:
384: return libraries.add(lEntry);
385: }
386:
387: public boolean addDependency(ProjectModel.UserLibrary uLibrary) {
388: logger.finest("added library dependency: " + "\""
389: + uLibrary.getName() + "\""); //NOI18N
390:
391: return dependencies.add(uLibrary);
392: }
393:
394: public String getName() {
395: return name;
396: }
397:
398: public Collection/*<AbstractProjectDefinition.AbstractLibraryEntry>*/getLibraries() {
399: return libraries;
400: }
401:
402: public final boolean fileNotFound() {
403: return fileNotFound;
404: }
405:
406: public final boolean isValid() {
407: boolean isValid = false;//no included library means invalid state
408: for (Iterator it = getLibraries().iterator(); it.hasNext();) {
409: AbstractProject.Library lEntry = (AbstractProject.Library) it
410: .next();
411: isValid = lEntry.isValid();
412: if (!isValid) {
413: break;
414: }
415:
416: }
417: return isValid;
418: }
419:
420: public String toString() {
421: StringBuffer sb = new StringBuffer();
422: sb.append(NbBundle.getMessage(AbstractProject.class,
423: "TXT_UserLibrary"));//NOI18N
424: sb.append((isValid()) ? "" : "!");//NOI18N
425: sb.append(getName());
426:
427: return sb.toString();
428: }
429:
430: public Collection getDependencies() {
431: return dependencies;
432: }
433:
434: }
435:
436: private static boolean isValid(File f) {
437: File srcFolder = FileUtil.normalizeFile(f);
438: return (srcFolder.isDirectory() && FileUtil
439: .toFileObject(srcFolder) != null);
440: }
441:
442: private static boolean isValidArchiv(File f) {
443: File srcFolder = FileUtil.normalizeFile(f);
444: FileObject srcFileObject = FileUtil.toFileObject(srcFolder);
445: return (srcFolder.exists() && srcFileObject != null)
446: && FileUtil.isArchiveFile(srcFileObject);
447: }
448:
449: public String toString() {
450: StringBuffer sb = new StringBuffer();
451:
452: sb.append(NbBundle.getMessage(AbstractProject.class,
453: "TXT_Project"));//NOI18N
454: sb.append(this .getName()).append("\n");//NOI18N
455:
456: Collection all = new ArrayList();
457: all.addAll(getSourceRoots());
458: all.addAll(getLibraries());
459: all.addAll(getUserLibraries());
460:
461: for (Iterator it = all.iterator(); it.hasNext();) {
462: sb.append(it.next().toString()).append("\n");//NOI18N
463: }
464:
465: for (Iterator it = getDependencies().iterator(); it.hasNext();) {
466: sb.append(NbBundle.getMessage(AbstractProject.class,
467: "TXT_Deps"));//NOI18N
468: sb.append(
469: ((AbstractProject) it.next()).getProjectDir()
470: .getPath()).append("\n");
471: }
472:
473: sb
474: .append(NbBundle.getMessage(AbstractProject.class,
475: "TXT_JDK"));//NOI18N
476: sb.append((getJDKDirectory() != null) ? getJDKDirectory()
477: .getAbsolutePath() : "!");//NOI18N
478:
479: return sb.toString();
480: }
481:
482: public String getJdkId() {
483: return jdkId;
484: }
485:
486: public void setJdkId(String jdkId) {
487: this.jdkId = jdkId;
488: }
489:
490: }
|