001: /*******************************************************************************
002: * Copyright (c) 2005, 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.pde.internal.core;
011:
012: import java.io.File;
013: import java.io.FileInputStream;
014: import java.io.FileOutputStream;
015: import java.io.IOException;
016: import java.util.Enumeration;
017: import java.util.Properties;
018:
019: import org.eclipse.core.resources.IProject;
020: import org.eclipse.core.runtime.IPath;
021: import org.eclipse.jdt.core.ElementChangedEvent;
022: import org.eclipse.jdt.core.IClasspathEntry;
023: import org.eclipse.jdt.core.IElementChangedListener;
024: import org.eclipse.jdt.core.IJavaElement;
025: import org.eclipse.jdt.core.IJavaElementDelta;
026: import org.eclipse.jdt.core.IJavaModel;
027: import org.eclipse.jdt.core.IJavaProject;
028: import org.eclipse.jdt.core.IPackageFragment;
029: import org.eclipse.jdt.core.IPackageFragmentRoot;
030: import org.eclipse.jdt.core.JavaCore;
031: import org.eclipse.jdt.core.JavaModelException;
032: import org.eclipse.pde.core.plugin.IPluginModelBase;
033: import org.eclipse.pde.core.plugin.PluginRegistry;
034:
035: public class JavaElementChangeListener implements
036: IElementChangedListener {
037:
038: private static final String FILENAME = "clean-cache.properties"; //$NON-NLS-1$
039:
040: private Properties fTable = new Properties();
041:
042: public void start() {
043: JavaCore.addElementChangedListener(this ,
044: ElementChangedEvent.POST_CHANGE);
045: load();
046: }
047:
048: /* (non-Javadoc)
049: * @see org.eclipse.jdt.core.IElementChangedListener#elementChanged(org.eclipse.jdt.core.ElementChangedEvent)
050: */
051: public void elementChanged(ElementChangedEvent event) {
052: handleDelta(event.getDelta());
053: }
054:
055: public void shutdown() {
056: JavaCore.removeElementChangedListener(this );
057: save();
058: }
059:
060: private void handleDelta(IJavaElementDelta delta) {
061: IJavaElement element = delta.getElement();
062:
063: if (element instanceof IJavaModel) {
064: handleChildDeltas(delta);
065: } else if (element instanceof IJavaProject) {
066: if (isInterestingProject((IJavaProject) element)) {
067: if (delta.getKind() == IJavaElementDelta.CHANGED) {
068: handleChildDeltas(delta);
069: } else if (delta.getKind() == IJavaElementDelta.ADDED) {
070: updateTable(element);
071: }
072: }
073: } else if (element instanceof IPackageFragmentRoot) {
074: handleChildDeltas(delta);
075: }
076: }
077:
078: private void handleChildDeltas(IJavaElementDelta delta) {
079: IJavaElementDelta[] deltas = delta.getAffectedChildren();
080: for (int i = 0; i < deltas.length; i++) {
081: if (ignoreDelta(deltas[i]))
082: continue;
083: if (isInterestingDelta(deltas[i])) {
084: updateTable(deltas[i].getElement());
085: break;
086: }
087: handleDelta(deltas[i]);
088: }
089: }
090:
091: private boolean isInterestingDelta(IJavaElementDelta delta) {
092: int kind = delta.getKind();
093: boolean interestingKind = kind == IJavaElementDelta.ADDED
094: || kind == IJavaElementDelta.REMOVED;
095:
096: IJavaElement element = delta.getElement();
097: boolean interestingElement = element instanceof IPackageFragment
098: || element instanceof IPackageFragmentRoot;
099:
100: if (interestingElement && interestingKind)
101: return true;
102:
103: if (kind == IJavaElementDelta.CHANGED
104: && element instanceof IPackageFragmentRoot) {
105: IPackageFragmentRoot root = (IPackageFragmentRoot) element;
106: return root.isArchive();
107: }
108: return false;
109: }
110:
111: private boolean ignoreDelta(IJavaElementDelta delta) {
112: try {
113: IJavaElement element = delta.getElement();
114: if (element instanceof IPackageFragmentRoot) {
115: IPackageFragmentRoot root = (IPackageFragmentRoot) element;
116: IClasspathEntry entry = root.getRawClasspathEntry();
117: if (entry != null
118: && entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER)
119: return true;
120: }
121: } catch (JavaModelException e) {
122: }
123: return false;
124: }
125:
126: private boolean isInterestingProject(IJavaProject jProject) {
127: IProject project = jProject.getProject();
128: return WorkspaceModelManager.isPluginProject(project)
129: && !WorkspaceModelManager.isBinaryProject(project)
130: && !project.exists(ICoreConstants.MANIFEST_PATH);
131: }
132:
133: private void updateTable(IJavaElement element) {
134: IJavaProject jProject = (IJavaProject) element
135: .getAncestor(IJavaElement.JAVA_PROJECT);
136: if (jProject != null) {
137: IProject project = jProject.getProject();
138: IPluginModelBase model = PluginRegistry.findModel(project);
139: if (model != null) {
140: String id = model.getPluginBase().getId();
141: if (id != null)
142: fTable.put(id, Long.toString(System
143: .currentTimeMillis()));
144: }
145: }
146: }
147:
148: private void save() {
149: // start by cleaning up extraneous keys.
150: Enumeration keys = fTable.keys();
151: while (keys.hasMoreElements()) {
152: String id = keys.nextElement().toString();
153: IPluginModelBase model = PluginRegistry.findModel(id);
154: if (model == null || model.getUnderlyingResource() == null)
155: fTable.remove(id);
156: }
157:
158: FileOutputStream stream = null;
159: try {
160: stream = new FileOutputStream(new File(getDirectory(),
161: FILENAME));
162: fTable.store(stream, "Cached timestamps"); //$NON-NLS-1$
163: stream.flush();
164: } catch (IOException e) {
165: PDECore.logException(e);
166: } finally {
167: try {
168: if (stream != null)
169: stream.close();
170: } catch (IOException e1) {
171: }
172: }
173: }
174:
175: private File getDirectory() {
176: IPath path = PDECore.getDefault().getStateLocation().append(
177: ".cache"); //$NON-NLS-1$
178: File directory = new File(path.toOSString());
179: if (!directory.exists() || !directory.isDirectory())
180: directory.mkdirs();
181: return directory;
182: }
183:
184: private void load() {
185: FileInputStream is = null;
186: try {
187: File file = new File(getDirectory(), FILENAME);
188: if (file.exists() && file.isFile()) {
189: is = new FileInputStream(file);
190: fTable.load(is);
191: }
192: } catch (IOException e) {
193: } finally {
194: try {
195: if (is != null) {
196: is.close();
197: }
198: } catch (IOException e1) {
199: }
200: }
201: }
202:
203: public void synchronizeManifests(File cacheDirectory) {
204: Enumeration keys = fTable.keys();
205: while (keys.hasMoreElements()) {
206: String id = keys.nextElement().toString();
207: IPluginModelBase model = PluginRegistry.findModel(id);
208: if (model != null) {
209: File file = new File(
210: cacheDirectory,
211: id
212: + "_" + model.getPluginBase().getVersion() + ".MF"); //$NON-NLS-1$ //$NON-NLS-2$
213: if (file.exists()
214: && file.isFile()
215: && file.lastModified() < Long.parseLong(fTable
216: .get(id).toString()))
217: file.delete();
218: }
219: }
220: }
221:
222: }
|