001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 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.preferences;
011:
012: import java.lang.reflect.InvocationTargetException;
013:
014: import org.eclipse.core.runtime.Assert;
015: import org.eclipse.core.runtime.CoreException;
016: import org.eclipse.core.runtime.IAdaptable;
017: import org.eclipse.core.runtime.IPath;
018: import org.eclipse.core.runtime.IProgressMonitor;
019: import org.eclipse.core.runtime.IStatus;
020:
021: import org.eclipse.core.resources.IFile;
022: import org.eclipse.core.resources.IProject;
023: import org.eclipse.core.resources.IResource;
024:
025: import org.eclipse.swt.SWT;
026: import org.eclipse.swt.widgets.Composite;
027: import org.eclipse.swt.widgets.Control;
028: import org.eclipse.swt.widgets.Shell;
029:
030: import org.eclipse.jface.dialogs.Dialog;
031: import org.eclipse.jface.operation.IRunnableWithProgress;
032:
033: import org.eclipse.ui.PlatformUI;
034: import org.eclipse.ui.dialogs.PropertyPage;
035:
036: import org.eclipse.jdt.core.ClasspathContainerInitializer;
037: import org.eclipse.jdt.core.IClasspathAttribute;
038: import org.eclipse.jdt.core.IClasspathContainer;
039: import org.eclipse.jdt.core.IClasspathEntry;
040: import org.eclipse.jdt.core.IJavaElement;
041: import org.eclipse.jdt.core.IJavaProject;
042: import org.eclipse.jdt.core.IPackageFragmentRoot;
043: import org.eclipse.jdt.core.JavaCore;
044: import org.eclipse.jdt.core.JavaModelException;
045:
046: import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
047: import org.eclipse.jdt.internal.corext.util.Messages;
048:
049: import org.eclipse.jdt.launching.JavaRuntime;
050:
051: import org.eclipse.jdt.internal.ui.JavaPlugin;
052: import org.eclipse.jdt.internal.ui.dialogs.StatusUtil;
053: import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
054: import org.eclipse.jdt.internal.ui.wizards.IStatusChangeListener;
055: import org.eclipse.jdt.internal.ui.wizards.buildpaths.ArchiveFileFilter;
056: import org.eclipse.jdt.internal.ui.wizards.buildpaths.BuildPathSupport;
057: import org.eclipse.jdt.internal.ui.wizards.buildpaths.CPListElement;
058:
059: public class NativeLibrariesPropertyPage extends PropertyPage implements
060: IStatusChangeListener {
061:
062: private NativeLibrariesConfigurationBlock fConfigurationBlock;
063: private boolean fIsValidElement;
064: private IClasspathEntry fEntry;
065: private IPath fContainerPath;
066:
067: /**
068: * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
069: */
070: public void createControl(Composite parent) {
071: IJavaElement elem = getJavaElement();
072: try {
073: if (elem instanceof IPackageFragmentRoot) {
074: IPackageFragmentRoot root = (IPackageFragmentRoot) elem;
075:
076: IClasspathEntry entry = root.getRawClasspathEntry();
077: if (entry == null) {
078: fIsValidElement = false;
079: setDescription(PreferencesMessages.NativeLibrariesPropertyPage_invalidElementSelection_desription);
080: } else {
081: if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
082: fContainerPath = entry.getPath();
083: fEntry = handleContainerEntry(fContainerPath,
084: elem.getJavaProject(), root.getPath());
085: fIsValidElement = fEntry != null;
086: } else {
087: fContainerPath = null;
088: fEntry = entry;
089: fIsValidElement = true;
090: }
091: }
092: } else {
093: fIsValidElement = false;
094: setDescription(PreferencesMessages.NativeLibrariesPropertyPage_invalidElementSelection_desription);
095: }
096: } catch (JavaModelException e) {
097: fIsValidElement = false;
098: setDescription(PreferencesMessages.NativeLibrariesPropertyPage_invalidElementSelection_desription);
099: }
100: super .createControl(parent);
101: }
102:
103: private IClasspathEntry handleContainerEntry(IPath containerPath,
104: IJavaProject jproject, IPath jarPath)
105: throws JavaModelException {
106: ClasspathContainerInitializer initializer = JavaCore
107: .getClasspathContainerInitializer(containerPath
108: .segment(0));
109: IClasspathContainer container = JavaCore.getClasspathContainer(
110: containerPath, jproject);
111: if (initializer == null || container == null) {
112: setDescription(Messages
113: .format(
114: PreferencesMessages.NativeLibrariesPropertyPage_invalid_container,
115: containerPath.toString()));
116: return null;
117: }
118: String containerName = container.getDescription();
119: IStatus status = initializer
120: .getAttributeStatus(containerPath, jproject,
121: JavaRuntime.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY);
122: if (status.getCode() == ClasspathContainerInitializer.ATTRIBUTE_NOT_SUPPORTED) {
123: setDescription(Messages
124: .format(
125: PreferencesMessages.NativeLibrariesPropertyPage_not_supported,
126: containerName));
127: return null;
128: }
129: if (status.getCode() == ClasspathContainerInitializer.ATTRIBUTE_READ_ONLY) {
130: setDescription(Messages
131: .format(
132: PreferencesMessages.NativeLibrariesPropertyPage_read_only,
133: containerName));
134: return null;
135: }
136: IClasspathEntry entry = JavaModelUtil.findEntryInContainer(
137: container, jarPath);
138: Assert.isNotNull(entry);
139: return entry;
140: }
141:
142: /**
143: * {@inheritDoc}
144: */
145: protected Control createContents(Composite parent) {
146: if (!fIsValidElement)
147: return new Composite(parent, SWT.NONE);
148:
149: IJavaElement elem = getJavaElement();
150: if (elem == null)
151: return new Composite(parent, SWT.NONE);
152:
153: String nativeLibPath = null;
154: IClasspathAttribute[] extraAttributes = fEntry
155: .getExtraAttributes();
156: for (int i = 0; i < extraAttributes.length; i++) {
157: if (extraAttributes[i].getName().equals(
158: JavaRuntime.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY)) {
159: nativeLibPath = extraAttributes[i].getValue();
160: break;
161: }
162: }
163: fConfigurationBlock = new NativeLibrariesConfigurationBlock(
164: this , getShell(), nativeLibPath, fEntry);
165: Control control = fConfigurationBlock.createContents(parent);
166: control.setVisible(elem != null);
167:
168: Dialog.applyDialogFont(control);
169: return control;
170: }
171:
172: /**
173: * {@inheritDoc}
174: */
175: public void statusChanged(IStatus status) {
176: setValid(!status.matches(IStatus.ERROR));
177: StatusUtil.applyToStatusLine(this , status);
178: }
179:
180: /*
181: * @see PreferencePage#performDefaults()
182: */
183: protected void performDefaults() {
184: if (fConfigurationBlock != null) {
185: fConfigurationBlock.performDefaults();
186: }
187: super .performDefaults();
188: }
189:
190: /**
191: * @see org.eclipse.jface.preference.IPreferencePage#performOk()
192: */
193: public boolean performOk() {
194: if (fConfigurationBlock != null) {
195: String nativeLibraryPath = fConfigurationBlock
196: .getNativeLibraryPath();
197: if (nativeLibraryPath == null) {
198: return true;//no change
199: }
200:
201: IJavaElement elem = getJavaElement();
202: try {
203: IRunnableWithProgress runnable = getRunnable(
204: getShell(), elem, nativeLibraryPath, fEntry,
205: fContainerPath);
206: PlatformUI.getWorkbench().getProgressService().run(
207: true, true, runnable);
208: } catch (InvocationTargetException e) {
209: String title = PreferencesMessages.NativeLibrariesPropertyPage_errorAttaching_title;
210: String message = PreferencesMessages.NativeLibrariesPropertyPage_errorAttaching_message;
211: ExceptionHandler.handle(e, getShell(), title, message);
212: return false;
213: } catch (InterruptedException e) {
214: // Canceled
215: return false;
216: }
217: }
218: return true;
219: }
220:
221: private static IRunnableWithProgress getRunnable(final Shell shell,
222: final IJavaElement elem, final String nativeLibraryPath,
223: final IClasspathEntry entry, final IPath containerPath) {
224: return new IRunnableWithProgress() {
225: public void run(IProgressMonitor monitor)
226: throws InvocationTargetException {
227: try {
228: IJavaProject project = elem.getJavaProject();
229: if (elem instanceof IPackageFragmentRoot) {
230: CPListElement cpElem = CPListElement
231: .createFromExisting(entry, project);
232: cpElem.setAttribute(
233: CPListElement.NATIVE_LIB_PATH,
234: nativeLibraryPath);
235: IClasspathEntry newEntry = cpElem
236: .getClasspathEntry();
237: String[] changedAttributes = { CPListElement.NATIVE_LIB_PATH };
238: BuildPathSupport.modifyClasspathEntry(shell,
239: newEntry, changedAttributes, project,
240: containerPath, monitor);
241: }
242: } catch (CoreException e) {
243: throw new InvocationTargetException(e);
244: }
245: }
246: };
247: }
248:
249: private IJavaElement getJavaElement() {
250: IAdaptable adaptable = getElement();
251: IJavaElement elem = (IJavaElement) adaptable
252: .getAdapter(IJavaElement.class);
253: if (elem == null) {
254:
255: IResource resource = (IResource) adaptable
256: .getAdapter(IResource.class);
257: //special case when the .jar is a file
258: try {
259: if (resource instanceof IFile
260: && ArchiveFileFilter.isArchivePath(resource
261: .getFullPath())) {
262: IProject proj = resource.getProject();
263: if (proj.hasNature(JavaCore.NATURE_ID)) {
264: IJavaProject jproject = JavaCore.create(proj);
265: elem = jproject
266: .getPackageFragmentRoot(resource); // create a handle
267: }
268: }
269: } catch (CoreException e) {
270: JavaPlugin.log(e);
271: }
272: }
273: return elem;
274: }
275:
276: }
|