001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.ui.jarpackager;
011:
012: import java.io.File;
013: import java.io.IOException;
014: import java.io.InputStream;
015: import java.util.ArrayList;
016: import java.util.Arrays;
017: import java.util.Iterator;
018: import java.util.List;
019: import java.util.jar.JarEntry;
020: import java.util.zip.CRC32;
021:
022: import org.eclipse.core.runtime.CoreException;
023: import org.eclipse.core.runtime.IStatus;
024: import org.eclipse.core.runtime.Status;
025:
026: import org.eclipse.core.resources.IContainer;
027: import org.eclipse.core.resources.IFile;
028: import org.eclipse.core.resources.IResource;
029:
030: import org.eclipse.swt.widgets.Display;
031: import org.eclipse.swt.widgets.Shell;
032:
033: import org.eclipse.jface.dialogs.MessageDialog;
034: import org.eclipse.jface.operation.IRunnableContext;
035:
036: import org.eclipse.jdt.core.IJavaElement;
037: import org.eclipse.jdt.core.IType;
038: import org.eclipse.jdt.core.JavaModelException;
039:
040: import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
041: import org.eclipse.jdt.internal.corext.util.Messages;
042:
043: import org.eclipse.jdt.ui.JavaUI;
044: import org.eclipse.jdt.ui.jarpackager.JarPackageData;
045:
046: import org.eclipse.jdt.internal.ui.IJavaStatusConstants;
047: import org.eclipse.jdt.internal.ui.JavaPlugin;
048:
049: /**
050: * Utility methods for JAR Import/Export.
051: */
052: public final class JarPackagerUtil {
053:
054: static final String JAR_EXTENSION = "jar"; //$NON-NLS-1$
055: static final String DESCRIPTION_EXTENSION = "jardesc"; //$NON-NLS-1$
056:
057: private static final String META_INF_ENTRY = "META-INF"; //$NON-NLS-1$
058: private static final String REFACTORINGS_ENTRY = META_INF_ENTRY
059: + "/REFACTORINGS.XML"; //$NON-NLS-1$
060:
061: private JarPackagerUtil() {
062: // Do nothing
063: }
064:
065: public static boolean askToCreateDirectory(final Shell parent,
066: File directory) {
067: if (parent == null)
068: return false;
069: return queryDialog(
070: parent,
071: JarPackagerMessages.JarPackage_confirmCreate_title,
072: Messages
073: .format(
074: JarPackagerMessages.JarPackage_confirmCreate_message,
075: directory.toString()));
076: }
077:
078: /**
079: * Returns the name of the refactorings zip entry.
080: *
081: * @return the name of the refactorings zip entry
082: *
083: * @since 3.2
084: */
085: public static String getRefactoringsEntry() {
086: return REFACTORINGS_ENTRY;
087: }
088:
089: /**
090: * Returns the name of the deprecations zip entry for the specified file.
091: *
092: * @param name
093: * the name of the file
094: * @return the name of the deprecations zip entry
095: *
096: * @since 3.2
097: */
098: public static String getDeprecationEntry(final String name) {
099: return META_INF_ENTRY + "/" + name; //$NON-NLS-1$
100: }
101:
102: /**
103: * Returns the name of the meta entry.
104: *
105: * @return the name of the meta entry
106: *
107: * @since 3.2
108: */
109: public static String getMetaEntry() {
110: return META_INF_ENTRY;
111: }
112:
113: /**
114: * Computes and returns the elements as resources.
115: * The underlying resource is used for Java elements.
116: *
117: * @return a List with the selected resources
118: */
119: public static List asResources(Object[] fSelectedElements) {
120: if (fSelectedElements == null)
121: return null;
122: List selectedResources = new ArrayList(fSelectedElements.length);
123: for (int i = 0; i < fSelectedElements.length; i++) {
124: Object element = fSelectedElements[i];
125: if (element instanceof IJavaElement) {
126: selectedResources.add(((IJavaElement) element)
127: .getResource());
128: } else if (element instanceof IResource)
129: selectedResources.add(element);
130: }
131: return selectedResources;
132: }
133:
134: public static boolean askForOverwritePermission(final Shell parent,
135: String filePath) {
136: if (parent == null)
137: return false;
138: return queryDialog(
139: parent,
140: JarPackagerMessages.JarPackage_confirmReplace_title,
141: Messages
142: .format(
143: JarPackagerMessages.JarPackage_confirmReplace_message,
144: filePath));
145: }
146:
147: /**
148: * Gets the name of the manifest's main class
149: *
150: * @return a string with the name
151: */
152: static String getMainClassName(JarPackageData jarPackage) {
153: if (jarPackage.getManifestMainClass() == null)
154: return ""; //$NON-NLS-1$
155: else
156: return jarPackage.getManifestMainClass()
157: .getFullyQualifiedName();
158: }
159:
160: private static boolean queryDialog(final Shell parent,
161: final String title, final String message) {
162: Display display = parent.getDisplay();
163: if (display == null || display.isDisposed())
164: return false;
165: final boolean[] returnValue = new boolean[1];
166: Runnable runnable = new Runnable() {
167: public void run() {
168: returnValue[0] = MessageDialog.openQuestion(parent,
169: title, message);
170: }
171: };
172: display.syncExec(runnable);
173: return returnValue[0];
174: }
175:
176: /**
177: * Creates a <code>CoreException</code> with the given parameters.
178: *
179: * @param message a string with the message
180: * @param ex the exception to be wrapped or <code>null</code> if none
181: * @return a CoreException
182: */
183: public static CoreException createCoreException(String message,
184: Exception ex) {
185: if (message == null)
186: message = ""; //$NON-NLS-1$
187: return new CoreException(new Status(IStatus.ERROR,
188: JavaUI.ID_PLUGIN, IJavaStatusConstants.INTERNAL_ERROR,
189: message, ex));
190: }
191:
192: /**
193: * Tells whether the specified manifest main class is valid.
194: *
195: * @return <code>true</code> if a main class is specified and valid
196: */
197: public static boolean isMainClassValid(JarPackageData data,
198: IRunnableContext context) {
199: if (data == null)
200: return false;
201:
202: IType mainClass = data.getManifestMainClass();
203: if (mainClass == null)
204: // no main class specified
205: return true;
206:
207: try {
208: // Check if main method is in scope
209: IFile file = (IFile) mainClass.getResource();
210: if (file == null
211: || !contains(asResources(data.getElements()), file))
212: return false;
213:
214: // Test if it has a main method
215: return JavaModelUtil.hasMainMethod(mainClass);
216: } catch (JavaModelException e) {
217: JavaPlugin.log(e.getStatus());
218: }
219: return false;
220: }
221:
222: static boolean contains(List resources, IFile file) {
223: if (resources == null || file == null)
224: return false;
225:
226: if (resources.contains(file))
227: return true;
228:
229: Iterator iter = resources.iterator();
230: while (iter.hasNext()) {
231: IResource resource = (IResource) iter.next();
232: if (resource != null
233: && resource.getType() != IResource.FILE) {
234: List children = null;
235: try {
236: children = Arrays.asList(((IContainer) resource)
237: .members());
238: } catch (CoreException ex) {
239: // ignore this folder
240: continue;
241: }
242: if (children != null && contains(children, file))
243: return true;
244: }
245: }
246: return false;
247: }
248:
249: /**
250: * Calculates the crc and size of the resource and updates the entry.
251: *
252: * @param entry
253: * the jar entry to update
254: * @param stream
255: * the input stream
256: * @param buffer
257: * a shared buffer to store temporary data
258: *
259: * @throws IOException
260: * if an input/output error occurs
261: */
262: public static void calculateCrcAndSize(final JarEntry entry,
263: final InputStream stream, final byte[] buffer)
264: throws IOException {
265: int size = 0;
266: final CRC32 crc = new CRC32();
267: int count;
268: try {
269: while ((count = stream.read(buffer, 0, buffer.length)) != -1) {
270: crc.update(buffer, 0, count);
271: size += count;
272: }
273: } finally {
274: if (stream != null) {
275: try {
276: stream.close();
277: } catch (IOException exception) {
278: // Do nothing
279: }
280: }
281: }
282: entry.setSize(size);
283: entry.setCrc(crc.getValue());
284: }
285: }
|