0001: /*******************************************************************************
0002: * Copyright (c) 2000, 2006 IBM Corporation and others.
0003: * All rights reserved. This program and the accompanying materials
0004: * are made available under the terms of the Eclipse Public License v1.0
0005: * which accompanies this distribution, and is available at
0006: * http://www.eclipse.org/legal/epl-v10.html
0007: *
0008: * Contributors:
0009: * IBM Corporation - initial API and implementation
0010: *******************************************************************************/package org.eclipse.jdt.ui.jarpackager;
0011:
0012: import java.io.InputStream;
0013: import java.io.OutputStream;
0014:
0015: import org.eclipse.core.resources.IFile;
0016: import org.eclipse.core.resources.IProject;
0017: import org.eclipse.core.resources.ResourcesPlugin;
0018:
0019: import org.eclipse.core.runtime.Assert;
0020: import org.eclipse.core.runtime.CoreException;
0021: import org.eclipse.core.runtime.IPath;
0022: import org.eclipse.core.runtime.Path;
0023:
0024: import org.eclipse.swt.widgets.Shell;
0025:
0026: import org.eclipse.jface.operation.IRunnableContext;
0027:
0028: import org.eclipse.ltk.core.refactoring.RefactoringDescriptorProxy;
0029:
0030: import org.eclipse.jdt.core.IPackageFragment;
0031: import org.eclipse.jdt.core.IType;
0032:
0033: import org.eclipse.jdt.internal.ui.JavaPlugin;
0034: import org.eclipse.jdt.internal.ui.jarpackager.JarFileExportOperation;
0035: import org.eclipse.jdt.internal.ui.jarpackager.JarPackageReader;
0036: import org.eclipse.jdt.internal.ui.jarpackager.JarPackageWriter;
0037: import org.eclipse.jdt.internal.ui.jarpackager.JarPackagerUtil;
0038: import org.eclipse.jdt.internal.ui.jarpackager.ManifestProvider;
0039: import org.eclipse.jdt.internal.ui.util.BusyIndicatorRunnableContext;
0040:
0041: /**
0042: * Model for a JAR package which stores information used during JAR export and
0043: * import.
0044: * <p>
0045: * Clients may subclass.
0046: * </p>
0047: *
0048: * @see org.eclipse.jdt.ui.jarpackager.JarWriter3
0049: * @since 2.0
0050: */
0051: public class JarPackageData {
0052:
0053: private String fManifestVersion;
0054:
0055: /*
0056: * What to export - internal locations
0057: * The list fExported* is null if fExport* is false)
0058: */
0059: private boolean fExportClassFiles; // export generated class files and resources
0060: private boolean fExportOutputFolders; // export all output folder of enclosing projects
0061: private boolean fExportJavaFiles; // export java files and resources
0062:
0063: /*
0064: * Source folder hierarchy is created in the JAR if true
0065: */
0066: private boolean fUseSourceFolderHierarchy;
0067:
0068: /*
0069: * Projects of which files are exported will be built if true
0070: * and auto-build is off.
0071: */
0072: private boolean fBuildIfNeeded;
0073:
0074: /*
0075: * Leaf elements (no containers) to export
0076: */
0077: private Object[] fElements; // inside workspace
0078:
0079: private IPath fJarLocation; // external location
0080: private boolean fOverwrite;
0081: private boolean fCompress;
0082:
0083: private boolean fSaveDescription;
0084: private IPath fDescriptionLocation; // internal location
0085:
0086: /*
0087: * A normal JAR has a manifest (fUsesManifest is true)
0088: * The manifest can be contributed in two ways
0089: * - it can be generated (fGenerateManifest is true) and
0090: * - saved (fSaveManifest is true)
0091: * - saved and reused (fReuseManifest is true implies: fSaveManifest is true)
0092: * - it can be specified (fGenerateManifest is false and the
0093: * manifest location must be specified (fManifestLocation))
0094: */
0095: private boolean fUsesManifest;
0096: private boolean fSaveManifest;
0097: private boolean fReuseManifest;
0098: private boolean fGenerateManifest;
0099: private IPath fManifestLocation; // internal location
0100:
0101: /*
0102: * Sealing: a JAR can be
0103: * - sealed (fSealJar is true) and a list of
0104: * unsealed packages can be defined (fPackagesToUnseal)
0105: * while the list of sealed packages is ignored
0106: * - unsealed (fSealJar is false) and the list of
0107: * sealed packages can be defined (fPackagesToSeal)
0108: * while the list of unsealed packages is ignored
0109: */
0110: private boolean fSealJar;
0111: private IPackageFragment[] fPackagesToSeal;
0112: private IPackageFragment[] fPackagesToUnseal;
0113:
0114: private IType fManifestMainClass;
0115:
0116: private String fComment; // the JAR comment
0117:
0118: /*
0119: * Error handling
0120: */
0121: private boolean fExportErrors;
0122: private boolean fExportWarnings;
0123:
0124: // The provider for the manifest file
0125: private IManifestProvider fManifestProvider;
0126:
0127: // Add directory entries to the jar
0128: private boolean fIncludeDirectoryEntries;
0129:
0130: // Projects for which to store refactoring information
0131: private IProject[] fRefactoringProjects = {};
0132:
0133: // Should the package be refactoring aware?
0134: private boolean fRefactoringAware = false;
0135:
0136: // Should the exporter only export refactorings causing structural changes?
0137: private boolean fRefactoringStructural = false;
0138:
0139: // Should the exporter include deprecation resolving information?
0140: private boolean fDeprecationAware = true;
0141:
0142: // The refactoring descriptors to export
0143: private RefactoringDescriptorProxy[] fRefactoringDescriptors = {};
0144:
0145: /**
0146: * Creates a new Jar Package Data structure
0147: */
0148: public JarPackageData() {
0149: setExportClassFiles(true);
0150: setExportOutputFolders(false);
0151: setUseSourceFolderHierarchy(false);
0152: setCompress(true);
0153: setSaveDescription(false);
0154: setJarLocation(Path.EMPTY);
0155: setDescriptionLocation(Path.EMPTY);
0156: setUsesManifest(true);
0157: setGenerateManifest(true);
0158: setReuseManifest(false);
0159: setSaveManifest(false);
0160: setManifestLocation(Path.EMPTY);
0161: setExportErrors(true);
0162: setExportWarnings(true);
0163: setBuildIfNeeded(true);
0164: setIncludeDirectoryEntries(false);
0165: }
0166:
0167: // ----------- Accessors -----------
0168:
0169: /**
0170: * Tells whether the JAR is compressed or not.
0171: *
0172: * @return <code>true</code> if the JAR is compressed
0173: */
0174: public boolean isCompressed() {
0175: return fCompress;
0176: }
0177:
0178: /**
0179: * Set whether the JAR is compressed or not.
0180: *
0181: * @param state a boolean indicating the new state
0182: */
0183: public void setCompress(boolean state) {
0184: fCompress = state;
0185: }
0186:
0187: /**
0188: * Tells whether files can be overwritten without warning.
0189: *
0190: * @return <code>true</code> if files can be overwritten without warning
0191: */
0192: public boolean allowOverwrite() {
0193: return fOverwrite;
0194: }
0195:
0196: /**
0197: * Sets whether files can be overwritten without warning.
0198: *
0199: * @param state a boolean indicating the new state
0200: */
0201: public void setOverwrite(boolean state) {
0202: fOverwrite = state;
0203: }
0204:
0205: /**
0206: * Tells whether class files and resources are exported.
0207: *
0208: * @return <code>true</code> if class files and resources are exported
0209: */
0210: public boolean areClassFilesExported() {
0211: return fExportClassFiles;
0212: }
0213:
0214: /**
0215: * Sets option to export class files and resources.
0216: *
0217: * @param state a boolean indicating the new state
0218: */
0219: public void setExportClassFiles(boolean state) {
0220: fExportClassFiles = state;
0221: }
0222:
0223: /**
0224: * Tells whether all output folders for the
0225: * enclosing projects of the exported elements.
0226: *
0227: * @return <code>true</code> if output folder are exported
0228: * @since 3.0
0229: */
0230: public boolean areOutputFoldersExported() {
0231: return fExportOutputFolders;
0232: }
0233:
0234: /**
0235: * Sets option to export all output folders for the
0236: * enclosing projects of the exported elements.
0237: *
0238: * @param state a boolean indicating the new state
0239: * @since 3.0
0240: */
0241: public void setExportOutputFolders(boolean state) {
0242: fExportOutputFolders = state;
0243: }
0244:
0245: /**
0246: * Tells whether files created by the Java builder are exported.
0247: *
0248: * @return <code>true</code> if output folder are exported
0249: * @since 3.0
0250: */
0251: public boolean areGeneratedFilesExported() {
0252: return fExportOutputFolders || fExportClassFiles;
0253: }
0254:
0255: /**
0256: * Tells whether java files and resources are exported.
0257: *
0258: * @return <code>true</code> if java files and resources are exported
0259: */
0260: public boolean areJavaFilesExported() {
0261: return fExportJavaFiles;
0262: }
0263:
0264: /**
0265: * Sets the option to export Java source and resources.
0266: *
0267: * @param state the new state
0268: */
0269: public void setExportJavaFiles(boolean state) {
0270: fExportJavaFiles = state;
0271: }
0272:
0273: /**
0274: * Tells whether the source folder hierarchy is used.
0275: * <p>
0276: * Using the source folder hierarchy only makes sense if
0277: * java files are but class files aren't exported.
0278: * </p>
0279: *
0280: * @return <code>true</code> if source folder hierarchy is used
0281: */
0282: public boolean useSourceFolderHierarchy() {
0283: return fUseSourceFolderHierarchy;
0284: }
0285:
0286: /**
0287: * Set the option to export the source folder hierarchy.
0288: *
0289: * @param state the new state
0290: */
0291: public void setUseSourceFolderHierarchy(boolean state) {
0292: fUseSourceFolderHierarchy = state;
0293: }
0294:
0295: /**
0296: * Gets the absolute location of the JAR file.
0297: * This path is normally external to the workspace.
0298: *
0299: * @return the absolute path representing the location of the JAR file
0300: *
0301: * @since 3.0
0302: */
0303: public IPath getAbsoluteJarLocation() {
0304: // The workspace root is always local to the file system.
0305: // So getLocation is OK here.
0306: IPath workspaceLocation = ResourcesPlugin.getWorkspace()
0307: .getRoot().getLocation();
0308: if (!fJarLocation.isAbsolute() && workspaceLocation != null)
0309: // prepend workspace path
0310: return workspaceLocation.append(fJarLocation);
0311: else
0312: return fJarLocation;
0313: }
0314:
0315: /**
0316: * Gets the location of the JAR file.
0317: * This path is normally external to the workspace.
0318: *
0319: * @return the path representing the location of the JAR file
0320: */
0321: public IPath getJarLocation() {
0322: return fJarLocation;
0323: }
0324:
0325: /**
0326: * Sets the JAR file location.
0327: *
0328: * @param jarLocation a path denoting the location of the JAR file
0329: */
0330: public void setJarLocation(IPath jarLocation) {
0331: fJarLocation = jarLocation;
0332: }
0333:
0334: /**
0335: * Tells whether the manifest file must be generated.
0336: *
0337: * @return <code>true</code> if the manifest has to be generated
0338: */
0339: public boolean isManifestGenerated() {
0340: return fGenerateManifest;
0341: }
0342:
0343: /**
0344: * Set whether a manifest must be generated or not.
0345: *
0346: * @param state the new state
0347: */
0348: public void setGenerateManifest(boolean state) {
0349: fGenerateManifest = state;
0350: }
0351:
0352: /**
0353: * Tells whether the manifest file must be saved to the
0354: * specified file during the export operation.
0355: *
0356: * @return <code>true</code> if the manifest must be saved
0357: * @see #getManifestLocation()
0358: */
0359: public boolean isManifestSaved() {
0360: return fSaveManifest;
0361: }
0362:
0363: /**
0364: * Sets whether the manifest file must be saved during export
0365: * operation or not.
0366: *
0367: * @param state the new state
0368: * @see #getManifestLocation()
0369: */
0370: public void setSaveManifest(boolean state) {
0371: fSaveManifest = state;
0372: if (!fSaveManifest)
0373: // can't reuse manifest if it is not saved
0374: setReuseManifest(false);
0375: }
0376:
0377: /**
0378: * Tells whether a previously generated manifest should be reused.
0379: *
0380: * @return <code>true</code> if the generated manifest will be reused when regenerating this JAR,
0381: * <code>false</code> if the manifest has to be regenerated
0382: */
0383: public boolean isManifestReused() {
0384: return fReuseManifest;
0385: }
0386:
0387: /**
0388: * Sets whether a previously generated manifest should be reused.
0389: *
0390: * @param state the new state
0391: */
0392: public void setReuseManifest(boolean state) {
0393: fReuseManifest = state;
0394: if (fReuseManifest)
0395: // manifest must be saved in order to be reused
0396: setSaveManifest(true);
0397: }
0398:
0399: /**
0400: * Returns the location of a user-defined manifest file.
0401: *
0402: * @return the path of the user-defined manifest file location,
0403: * or <code>null</code> if none is specified
0404: */
0405: public IPath getManifestLocation() {
0406: return fManifestLocation;
0407: }
0408:
0409: /**
0410: * Sets the location of a user-defined manifest file.
0411: *
0412: * @param manifestLocation the path of the user-define manifest location
0413: */
0414: public void setManifestLocation(IPath manifestLocation) {
0415: fManifestLocation = manifestLocation;
0416: }
0417:
0418: /**
0419: * Gets the manifest file (as workspace resource).
0420: *
0421: * @return a file which points to the manifest
0422: */
0423: public IFile getManifestFile() {
0424: IPath path = getManifestLocation();
0425: if (path.isValidPath(path.toString())
0426: && path.segmentCount() >= 2)
0427: return JavaPlugin.getWorkspace().getRoot().getFile(path);
0428: else
0429: return null;
0430: }
0431:
0432: /**
0433: * Gets the manifest version.
0434: *
0435: * @return a string containing the manifest version
0436: */
0437: public String getManifestVersion() {
0438: if (fManifestVersion == null)
0439: return "1.0"; //$NON-NLS-1$
0440: return fManifestVersion;
0441: }
0442:
0443: /**
0444: * Sets the manifest version.
0445: *
0446: * @param manifestVersion the string which contains the manifest version
0447: */
0448: public void setManifestVersion(String manifestVersion) {
0449: fManifestVersion = manifestVersion;
0450: }
0451:
0452: /**
0453: * Answers whether a manifest must be included in the JAR.
0454: *
0455: * @return <code>true</code> if a manifest has to be included
0456: */
0457: public boolean usesManifest() {
0458: return fUsesManifest;
0459: }
0460:
0461: /**
0462: * Sets whether a manifest must be included in the JAR.
0463: *
0464: * @param state the new state
0465: */
0466: public void setUsesManifest(boolean state) {
0467: fUsesManifest = state;
0468: }
0469:
0470: /**
0471: * Gets the manifest provider for this JAR package.
0472: *
0473: * @return the IManifestProvider
0474: */
0475: public IManifestProvider getManifestProvider() {
0476: if (fManifestProvider == null)
0477: fManifestProvider = new ManifestProvider();
0478: return fManifestProvider;
0479: }
0480:
0481: /**
0482: * Sets the manifest provider.
0483: *
0484: * @param manifestProvider the ManifestProvider to set
0485: */
0486: public void setManifestProvider(IManifestProvider manifestProvider) {
0487: fManifestProvider = manifestProvider;
0488: }
0489:
0490: /**
0491: * Answers whether the JAR itself is sealed.
0492: * The manifest will contain a "Sealed: true" statement.
0493: * <p>
0494: * This option should only be considered when the
0495: * manifest file is generated.
0496: * </p>
0497: *
0498: * @return <code>true</code> if the JAR must be sealed
0499: * @see #isManifestGenerated()
0500: */
0501: public boolean isJarSealed() {
0502: return fSealJar;
0503: }
0504:
0505: /**
0506: * Sets whether the JAR itself is sealed.
0507: * The manifest will contain the following entry:
0508: * Sealed: true
0509: * <p>
0510: * This option should only be considered when the
0511: * manifest file is generated.
0512: * </p>
0513: *
0514: * @param sealJar <code>true</code> if the JAR must be sealed
0515: * @see #isManifestGenerated()
0516: */
0517: public void setSealJar(boolean sealJar) {
0518: fSealJar = sealJar;
0519: }
0520:
0521: /**
0522: * Sets the packages which should be sealed.
0523: * The following entry will be added to the manifest file for each package:
0524: * Name: <name of the package>
0525: * Sealed: true
0526: * <p>
0527: * This should only be used if the JAR itself is not sealed.
0528: * </p>
0529: *
0530: * @param packagesToSeal an array of <code>IPackageFragment</code> to seal
0531: */
0532: public void setPackagesToSeal(IPackageFragment[] packagesToSeal) {
0533: fPackagesToSeal = packagesToSeal;
0534: }
0535:
0536: /**
0537: * Gets the packages which should be sealed.
0538: * The following entry will be added to the manifest file for each package:
0539: * Name: <name of the package>
0540: * Sealed: true
0541: * <p>
0542: * This should only be used if the JAR itself is not sealed.
0543: * </p>
0544: *
0545: * @return an array of <code>IPackageFragment</code>
0546: */
0547: public IPackageFragment[] getPackagesToSeal() {
0548: if (fPackagesToSeal == null)
0549: return new IPackageFragment[0];
0550: else
0551: return fPackagesToSeal;
0552: }
0553:
0554: /**
0555: * Gets the packages which should explicitly be unsealed.
0556: * The following entry will be added to the manifest file for each package:
0557: * Name: <name of the package>
0558: * Sealed: false
0559: * <p>
0560: * This should only be used if the JAR itself is sealed.
0561: * </p>
0562: *
0563: * @return an array of <code>IPackageFragment</code>
0564: */
0565: public IPackageFragment[] getPackagesToUnseal() {
0566: if (fPackagesToUnseal == null)
0567: return new IPackageFragment[0];
0568: else
0569: return fPackagesToUnseal;
0570: }
0571:
0572: /**
0573: * Set the packages which should explicitly be unsealed.
0574: * The following entry will be added to the manifest file for each package:
0575: * Name: <name of the package>
0576: * Sealed: false
0577: * <p>
0578: * This should only be used if the JAR itself is sealed.
0579: * </p>
0580: *
0581: * @param packagesToUnseal an array of <code>IPackageFragment</code>
0582: */
0583: public void setPackagesToUnseal(IPackageFragment[] packagesToUnseal) {
0584: fPackagesToUnseal = packagesToUnseal;
0585: }
0586:
0587: /**
0588: * Tells whether a description of this JAR package must be saved
0589: * to a file by a JAR description writer during the export operation.
0590: * <p>
0591: * The JAR writer defines the format of the file.
0592: * </p>
0593: *
0594: * @return <code>true</code> if this JAR package will be saved
0595: * @see #getDescriptionLocation()
0596: */
0597: public boolean isDescriptionSaved() {
0598: return fSaveDescription;
0599: }
0600:
0601: /**
0602: * Set whether a description of this JAR package must be saved
0603: * to a file by a JAR description writer during the export operation.
0604: * <p>
0605: * The format is defined by the client who implements the
0606: * reader/writer pair.
0607: * </p>
0608: * @param state a boolean containing the new state
0609: * @see #getDescriptionLocation()
0610: * @see IJarDescriptionWriter
0611: */
0612: public void setSaveDescription(boolean state) {
0613: fSaveDescription = state;
0614: }
0615:
0616: /**
0617: * Returns the location of file containing the description of a JAR.
0618: * This location is inside the workspace.
0619: *
0620: * @return the path of the description file location,
0621: * or <code>null</code> if none is specified
0622: */
0623: public IPath getDescriptionLocation() {
0624: return fDescriptionLocation;
0625: }
0626:
0627: /**
0628: * Set the location of the JAR description file.
0629: *
0630: * @param descriptionLocation the path of location
0631: */
0632: public void setDescriptionLocation(IPath descriptionLocation) {
0633: fDescriptionLocation = descriptionLocation;
0634: }
0635:
0636: /**
0637: * Gets the description file (as workspace resource).
0638: *
0639: * @return a file which points to the description
0640: */
0641: public IFile getDescriptionFile() {
0642: IPath path = getDescriptionLocation();
0643: if (path.isValidPath(path.toString())
0644: && path.segmentCount() >= 2)
0645: return JavaPlugin.getWorkspace().getRoot().getFile(path);
0646: else
0647: return null;
0648: }
0649:
0650: /**
0651: * Gets the manifest's main class.
0652: *
0653: * @return the type which contains the main class or,
0654: * <code>null</code> if none is specified
0655: */
0656: public IType getManifestMainClass() {
0657: return fManifestMainClass;
0658: }
0659:
0660: /**
0661: * Set the manifest's main class.
0662: *
0663: * @param manifestMainClass the type with the main class for the manifest file
0664: */
0665: public void setManifestMainClass(IType manifestMainClass) {
0666: fManifestMainClass = manifestMainClass;
0667: }
0668:
0669: /**
0670: * Returns the elements which will be exported.
0671: * These elements are leaf objects e.g. <code>IFile</code>
0672: * and not containers.
0673: *
0674: * @return an array of leaf objects
0675: */
0676: public Object[] getElements() {
0677: if (fElements == null)
0678: setElements(new Object[0]);
0679: return fElements;
0680: }
0681:
0682: /**
0683: * Set the elements which will be exported.
0684: *
0685: * These elements are leaf objects e.g. <code>IFile</code>.
0686: * and not containers.
0687: *
0688: * @param elements an array with leaf objects
0689: */
0690: public void setElements(Object[] elements) {
0691: fElements = elements;
0692: }
0693:
0694: /**
0695: * Returns the JAR's comment.
0696: *
0697: * @return the comment string or <code>null</code>
0698: * if the JAR does not contain a comment
0699: */
0700: public String getComment() {
0701: return fComment;
0702: }
0703:
0704: /**
0705: * Sets the JAR's comment.
0706: *
0707: * @param comment a string or <code>null</code>
0708: * if the JAR does not contain a comment
0709: */
0710: public void setComment(String comment) {
0711: fComment = comment;
0712: }
0713:
0714: /**
0715: * Tell whether errors are logged.
0716: * <p>
0717: * The export operation decides where and
0718: * how the errors are logged.
0719: * </p>
0720: *
0721: * @return <code>true</code> if errors are logged
0722: * @deprecated will be removed in final 2.0
0723: */
0724: public boolean logErrors() {
0725: return true;
0726: }
0727:
0728: /**
0729: * Sets whether errors are logged.
0730: * <p>
0731: * The export operation decides where and
0732: * how the errors are logged.
0733: * </p>
0734: *
0735: * @param logErrors <code>true</code> if errors are logged
0736: * @deprecated will be removed in final 2.0
0737: */
0738: public void setLogErrors(boolean logErrors) {
0739: // always true
0740: }
0741:
0742: /**
0743: * Tells whether warnings are logged or not.
0744: * <p>
0745: * The export operation decides where and
0746: * how the warnings are logged.
0747: * </p>
0748: *
0749: * @return <code>true</code> if warnings are logged
0750: * @deprecated will be removed in final 2.0
0751: */
0752: public boolean logWarnings() {
0753: return true;
0754: }
0755:
0756: /**
0757: * Sets if warnings are logged.
0758: * <p>
0759: * The export operation decides where and
0760: * how the warnings are logged.
0761: * </p>
0762: *
0763: * @param logWarnings <code>true</code> if warnings are logged
0764: * @deprecated will be removed in final 2.0
0765: */
0766: public void setLogWarnings(boolean logWarnings) {
0767: // always true
0768: }
0769:
0770: /**
0771: * Answers if compilation units with errors are exported.
0772: *
0773: * @return <code>true</code> if CUs with errors should be exported
0774: */
0775: public boolean areErrorsExported() {
0776: return fExportErrors;
0777: }
0778:
0779: /**
0780: * Sets if compilation units with errors are exported.
0781: *
0782: * @param exportErrors <code>true</code> if CUs with errors should be exported
0783: */
0784: public void setExportErrors(boolean exportErrors) {
0785: fExportErrors = exportErrors;
0786: }
0787:
0788: /**
0789: * Answers if compilation units with warnings are exported.
0790: *
0791: * @return <code>true</code> if CUs with warnings should be exported
0792: */
0793: public boolean exportWarnings() {
0794: return fExportWarnings;
0795: }
0796:
0797: /**
0798: * Sets if compilation units with warnings are exported.
0799: *
0800: * @param exportWarnings <code>true</code> if CUs with warnings should be exported
0801: */
0802: public void setExportWarnings(boolean exportWarnings) {
0803: fExportWarnings = exportWarnings;
0804: }
0805:
0806: /**
0807: * Answers if a build should be performed before exporting files.
0808: * This flag is only considered if auto-build is off.
0809: *
0810: * @return a boolean telling if a build should be performed
0811: */
0812: public boolean isBuildingIfNeeded() {
0813: return fBuildIfNeeded;
0814: }
0815:
0816: /**
0817: * Sets if a build should be performed before exporting files.
0818: * This flag is only considered if auto-build is off.
0819: *
0820: * @param buildIfNeeded a boolean telling if a build should be performed
0821: */
0822: public void setBuildIfNeeded(boolean buildIfNeeded) {
0823: fBuildIfNeeded = buildIfNeeded;
0824: }
0825:
0826: // ----------- Utility methods -----------
0827:
0828: /**
0829: * Finds the class files for the given java file
0830: * and returns them.
0831: * <p>
0832: * This is a hook for subclasses which want to implement
0833: * a different strategy for finding the class files. The default
0834: * strategy is to query the class files for the source file
0835: * name attribute. If this attribute is missing then all class
0836: * files in the corresponding output folder are exported.
0837: * </p>
0838: * <p>
0839: * A CoreException can be thrown if an error occurs during this
0840: * operation. The <code>CoreException</code> will not stop the export
0841: * process but adds the status object to the status of the
0842: * export runnable.
0843: * </p>
0844: *
0845: * @param javaFile a .java file
0846: * @return an array with class files or <code>null</code> to used the default strategy
0847: * @throws CoreException if find failed, e.g. I/O error or resource out of sync
0848: * @see IJarExportRunnable#getStatus()
0849: */
0850: public IFile[] findClassfilesFor(IFile javaFile)
0851: throws CoreException {
0852: return null;
0853: }
0854:
0855: /**
0856: * Creates and returns a JarWriter for this JAR package.
0857: *
0858: * @param parent the shell used to display question dialogs,
0859: * or <code>null</code> if "false/no/cancel" is the answer
0860: * and no dialog should be shown
0861: * @return a JarWriter2
0862: * @see JarWriter2
0863: * @throws CoreException if an unexpected exception happens
0864: *
0865: * @deprecated Use {@link #createJarWriter3(Shell)} instead
0866: */
0867: public JarWriter2 createJarWriter(Shell parent)
0868: throws CoreException {
0869: return new JarWriter2(this , parent);
0870: }
0871:
0872: /**
0873: * Creates and returns a JarWriter for this JAR package.
0874: *
0875: * @param parent the shell used to display question dialogs,
0876: * or <code>null</code> if "false/no/cancel" is the answer
0877: * and no dialog should be shown
0878: * @return a JarWriter3
0879: * @see JarWriter3
0880: * @throws CoreException if an unexpected exception happens
0881: *
0882: * @since 3.2
0883: */
0884: public JarWriter3 createJarWriter3(Shell parent)
0885: throws CoreException {
0886: return new JarWriter3(this , parent);
0887: }
0888:
0889: /**
0890: * Creates and returns a JarExportRunnable.
0891: *
0892: * @param parent the parent for the dialog,
0893: * or <code>null</code> if no questions should be asked and
0894: * no checks for unsaved files should be made.
0895: * @return a JarExportRunnable
0896: */
0897: public IJarExportRunnable createJarExportRunnable(Shell parent) {
0898: return new JarFileExportOperation(this , parent);
0899: }
0900:
0901: /**
0902: * Creates and returns a JarExportRunnable for a list of JAR package
0903: * data objects.
0904: *
0905: * @param jarPackagesData an array with JAR package data objects
0906: * @param parent the parent for the dialog,
0907: * or <code>null</code> if no dialog should be presented
0908: * @return the {@link IJarExportRunnable}
0909: */
0910: public IJarExportRunnable createJarExportRunnable(
0911: JarPackageData[] jarPackagesData, Shell parent) {
0912: return new JarFileExportOperation(jarPackagesData, parent);
0913: }
0914:
0915: /**
0916: * Creates and returns a JAR package data description writer
0917: * for this JAR package data object.
0918: * <p>
0919: * It is the client's responsibility to close this writer.
0920: * </p>
0921: * @param outputStream the output stream to write to
0922: * @return a JarWriter
0923: * @deprecated Use {@link #createJarDescriptionWriter(OutputStream, String)} instead
0924: */
0925: public IJarDescriptionWriter createJarDescriptionWriter(
0926: OutputStream outputStream) {
0927: return new JarPackageWriter(outputStream, "UTF-8"); //$NON-NLS-1$
0928: }
0929:
0930: /**
0931: * Creates and returns a JAR package data description writer
0932: * for this JAR package data object.
0933: * <p>
0934: * It is the client's responsibility to close this writer.
0935: * </p>
0936: * @param outputStream the output stream to write to
0937: * @param encoding the encoding to use
0938: * @return a JarWriter
0939: * @since 3.3
0940: */
0941: public IJarDescriptionWriter createJarDescriptionWriter(
0942: OutputStream outputStream, String encoding) {
0943: return new JarPackageWriter(outputStream, encoding);
0944: }
0945:
0946: /**
0947: * Creates and returns a JAR package data description reader
0948: * for this JAR package data object.
0949: * <p>
0950: * It is the client's responsibility to close this reader.
0951: * </p>
0952: * @param inputStream the input stream to read from
0953: * @return a JarWriter
0954: */
0955: public IJarDescriptionReader createJarDescriptionReader(
0956: InputStream inputStream) {
0957: return new JarPackageReader(inputStream);
0958: }
0959:
0960: /**
0961: * Tells whether this JAR package data can be used to generate
0962: * a valid JAR.
0963: *
0964: * @return <code>true</code> if the JAR Package info is valid
0965: */
0966: public boolean isValid() {
0967: return (areGeneratedFilesExported() || areJavaFilesExported())
0968: && getElements() != null && getElements().length > 0
0969: && getAbsoluteJarLocation() != null
0970: && isManifestAccessible()
0971: && isMainClassValid(new BusyIndicatorRunnableContext());
0972: }
0973:
0974: /**
0975: * Tells whether a manifest is available.
0976: *
0977: * @return <code>true</code> if the manifest is generated or the provided one is accessible
0978: */
0979: public boolean isManifestAccessible() {
0980: if (isManifestGenerated())
0981: return true;
0982: IFile file = getManifestFile();
0983: return file != null && file.isAccessible();
0984: }
0985:
0986: /**
0987: * Tells whether the specified manifest main class is valid.
0988: *
0989: * @param context the {@link IRunnableContext}
0990: * @return <code>true</code> if a main class is specified and valid
0991: */
0992: public boolean isMainClassValid(IRunnableContext context) {
0993: return JarPackagerUtil.isMainClassValid(this , context);
0994: }
0995:
0996: /**
0997: * Tells whether directory entries are added to the jar.
0998: *
0999: * @return <code>true</code> if directory entries are to be included
1000: *
1001: * @since 3.1
1002: */
1003: public boolean areDirectoryEntriesIncluded() {
1004: return fIncludeDirectoryEntries;
1005: }
1006:
1007: /**
1008: * Sets the option to include directory entries into the jar.
1009: *
1010: * @param includeDirectoryEntries <code>true</code> to include
1011: * directory entries <code>false</code> otherwise
1012: *
1013: * @since 3.1
1014: */
1015: public void setIncludeDirectoryEntries(
1016: boolean includeDirectoryEntries) {
1017: fIncludeDirectoryEntries = includeDirectoryEntries;
1018: }
1019:
1020: /**
1021: * Returns the projects for which refactoring information should be stored.
1022: * <p>
1023: * This information is used for JAR export.
1024: * </p>
1025: *
1026: * @return the projects for which refactoring information should be stored,
1027: * or an empty array
1028: *
1029: * @since 3.2
1030: */
1031: public IProject[] getRefactoringProjects() {
1032: return fRefactoringProjects;
1033: }
1034:
1035: /**
1036: * Is the JAR export wizard only exporting refactorings causing structural
1037: * changes?
1038: * <p>
1039: * This information is used for JAR export.
1040: * </p>
1041: *
1042: * @return <code>true</code> if exporting structural changes only,
1043: * <code>false</code> otherwise
1044: * @since 3.2
1045: */
1046: public boolean isExportStructuralOnly() {
1047: return fRefactoringStructural;
1048: }
1049:
1050: /**
1051: * Is the JAR package refactoring aware?
1052: * <p>
1053: * This information is used both in JAR export and import
1054: * </p>
1055: *
1056: * @return <code>true</code> if it is refactoring aware,
1057: * <code>false</code> otherwise
1058: *
1059: * @since 3.2
1060: */
1061: public boolean isRefactoringAware() {
1062: return fRefactoringAware;
1063: }
1064:
1065: /**
1066: * Is the JAR package deprecation aware?
1067: * <p>
1068: * This information is used in JAR export.
1069: * </p>
1070: *
1071: * @return <code>true</code> if it is deprecation aware,
1072: * <code>false</code> otherwise
1073: *
1074: * @since 3.2
1075: */
1076: public boolean isDeprecationAware() {
1077: return fDeprecationAware;
1078: }
1079:
1080: /**
1081: * Sets the projects for which refactoring information should be stored.
1082: * <p>
1083: * This information is used for JAR export.
1084: * </p>
1085: *
1086: * @param projects
1087: * the projects for which refactoring information should be
1088: * stored
1089: *
1090: * @since 3.2
1091: */
1092: public void setRefactoringProjects(IProject[] projects) {
1093: Assert.isNotNull(projects);
1094: fRefactoringProjects = projects;
1095: }
1096:
1097: /**
1098: * Determines whether the jar package is refactoring aware.
1099: * <p>
1100: * This information is used both in JAR export and import.
1101: * </p>
1102: *
1103: * @param aware
1104: * <code>true</code> if it is refactoring aware,
1105: * <code>false</code> otherwise
1106: *
1107: * @since 3.2
1108: */
1109: public void setRefactoringAware(boolean aware) {
1110: fRefactoringAware = aware;
1111: }
1112:
1113: /**
1114: * Determines whether the jar package is deprecation aware.
1115: * <p>
1116: * This information is used in JAR export.
1117: * </p>
1118: *
1119: * @param aware
1120: * <code>true</code> if it is deprecation aware,
1121: * <code>false</code> otherwise
1122: *
1123: * @since 3.2
1124: */
1125: public void setDeprecationAware(boolean aware) {
1126: fDeprecationAware = aware;
1127: }
1128:
1129: /**
1130: * Sets the refactoring descriptors to export.
1131: * <p>
1132: * This information is used in JAR export.
1133: * </p>
1134: *
1135: * @param descriptors
1136: * the refactoring descriptors
1137: *
1138: * @since 3.2
1139: */
1140: public void setRefactoringDescriptors(
1141: RefactoringDescriptorProxy[] descriptors) {
1142: Assert.isNotNull(descriptors);
1143: fRefactoringDescriptors = descriptors;
1144: }
1145:
1146: /**
1147: * Returns the refactoring descriptors to export.
1148: * <p>
1149: * This information is used in JAR export.
1150: * </p>
1151: *
1152: * @return the refactoring descriptors to export
1153: *
1154: * @since 3.2
1155: */
1156: public RefactoringDescriptorProxy[] getRefactoringDescriptors() {
1157: return fRefactoringDescriptors;
1158: }
1159:
1160: /**
1161: * Determines whether the jar packager exports only refactorings causing
1162: * structural changes.
1163: * <p>
1164: * This information is used for JAR export.
1165: * </p>
1166: *
1167: * @param structural
1168: * <code>true</code> if it exports only refactorings causing
1169: * structural changes, <code>false</code> otherwise
1170: *
1171: * @since 3.2
1172: */
1173: public void setExportStructuralOnly(boolean structural) {
1174: fRefactoringStructural = structural;
1175: }
1176: }
|