| package org.eclipse.jst.j2ee.internal.web.classpath; |
| |
| import java.io.BufferedInputStream; |
| import java.io.BufferedOutputStream; |
| import java.io.FileInputStream; |
| import java.io.FileNotFoundException; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.io.ObjectInputStream; |
| import java.io.ObjectOutputStream; |
| import java.io.Serializable; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Map.Entry; |
| |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.ISafeRunnable; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.SafeRunner; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.jobs.Job; |
| import org.eclipse.jst.j2ee.internal.web.plugin.WebPlugin; |
| |
| public class WebAppLibrariesStore { |
| |
| private static final String WEB_LIBRARIES_CACHE = "webLibrariesCache.index"; //$NON-NLS-1$ |
| private static Map<String, RestoreState> restoreStateMap; |
| private static Map<String, RestoreState> saveStateMap = new HashMap<String, RestoreState>(); |
| |
| static class RestoreState implements Serializable { |
| private static final long serialVersionUID = 5565856269776724522L; |
| transient boolean needToVerify; |
| List<String> pathStrings; |
| transient List<IPath> paths; |
| |
| private void writeObject(java.io.ObjectOutputStream out) throws IOException { |
| pathStrings = new ArrayList<String>(paths.size()); |
| for (IPath p : paths) { |
| pathStrings.add(p.toString()); |
| } |
| out.defaultWriteObject(); |
| } |
| |
| private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { |
| in.defaultReadObject(); |
| needToVerify = true; |
| paths = new ArrayList<IPath>(pathStrings.size()); |
| for (String s : pathStrings) { |
| paths.add(new Path(s)); |
| } |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| if (this == o) { |
| return true; |
| } else if (o == null) { |
| return false; |
| } else if (o instanceof RestoreState) { |
| RestoreState other = (RestoreState) o; |
| if (paths == null) { |
| return other.paths == null; |
| } |
| return paths.equals(other.paths); |
| } |
| return false; |
| } |
| |
| @Override |
| public int hashCode() { |
| if (paths == null) { |
| return 11; |
| } |
| return paths.hashCode(); |
| } |
| } |
| |
| static { |
| IPath stateLocation = WebPlugin.getDefault().getStateLocation(); |
| java.io.File file = stateLocation.append(WEB_LIBRARIES_CACHE).toFile(); |
| try{ |
| if (file.exists()) { |
| FileInputStream fIn = null; |
| boolean deleteCache = true; |
| try { |
| fIn = new FileInputStream(file); |
| BufferedInputStream bIn = new BufferedInputStream(fIn); |
| ObjectInputStream oIn = new ObjectInputStream(bIn); |
| restoreStateMap = (HashMap<String, RestoreState>) oIn.readObject(); |
| oIn.close(); |
| |
| //it is unfortunate this is necessary, but without iterating over the map |
| //and explicitly testing each value, class cast exceptions may occur later |
| //best to check them all now and recover |
| Iterator<Entry<String, RestoreState>> iterator = restoreStateMap.entrySet().iterator(); |
| while(iterator.hasNext()){ |
| Entry<String, RestoreState> next = iterator.next(); |
| String s = next.getKey(); |
| RestoreState rs = next.getValue(); |
| if(s == null || rs == null){ |
| //may throw ClassCastException |
| } |
| } |
| deleteCache = false; |
| } catch (FileNotFoundException e) { |
| WebPlugin.logError(e); |
| } catch (IOException e) { |
| WebPlugin.logError(e); |
| } catch (ClassNotFoundException e) { |
| WebPlugin.logError(e); |
| } catch (ClassCastException e) { |
| WebPlugin.logError(e); |
| } finally { |
| if (fIn != null) { |
| try { |
| fIn.close(); |
| } catch (IOException e) { |
| WebPlugin.logError(e); |
| } |
| } |
| if (deleteCache) { |
| restoreStateMap = new HashMap<String, RestoreState>(); |
| file.delete(); |
| } |
| } |
| } |
| } catch (Throwable e){ |
| try{ |
| WebPlugin.logError(e); |
| file.delete(); |
| } catch (Exception e2){ |
| //eat it |
| } |
| restoreStateMap = new HashMap<String, RestoreState>(); |
| } finally { |
| if(restoreStateMap == null) { |
| restoreStateMap = new HashMap<String, RestoreState>(); |
| } |
| } |
| |
| } |
| |
| public static RestoreState getRestoreState(String projectName) { |
| RestoreState restoreState = null; |
| synchronized (restoreStateMap) { |
| restoreState = restoreStateMap.get(projectName); |
| } |
| if (restoreState != null) { |
| synchronized (saveStateMap) { |
| saveStateMap.put(projectName, restoreState); |
| } |
| } |
| return restoreState; |
| } |
| |
| static void flush(String projectName) { |
| synchronized (restoreStateMap) { |
| restoreStateMap.remove(projectName); |
| } |
| synchronized (saveStateMap) { |
| saveStateMap.remove(projectName); |
| } |
| } |
| |
| private static class PersistJob extends Job { |
| |
| public PersistJob() { |
| super("Persist Web App Libraries State"); //$NON-NLS-1$ |
| setSystem(true); |
| setRule(null); |
| } |
| |
| @Override |
| protected IStatus run(IProgressMonitor monitor) { |
| SafeRunner.run(new ISafeRunnable() { |
| public void run() throws Exception { |
| persist(); |
| } |
| |
| public void handleException(Throwable exception) { |
| WebPlugin.logError(exception); |
| } |
| }); |
| return Status.OK_STATUS; |
| } |
| } |
| |
| private static int persistDelay = 60000; // 1 minute |
| private static PersistJob persistJob = new PersistJob(); |
| |
| static void saveState(String projectName, List<IPath> paths) { |
| RestoreState toSave = new RestoreState(); |
| toSave.paths = paths; |
| |
| boolean scheduleJob = false; |
| |
| synchronized (saveStateMap) { |
| RestoreState previous = saveStateMap.get(projectName); |
| if (null == previous || !previous.equals(toSave)) { |
| saveStateMap.put(projectName, toSave); |
| scheduleJob = true; |
| } |
| } |
| if (scheduleJob) { |
| synchronized (restoreStateMap) { |
| // if it changed, do not load it from the cache again |
| restoreStateMap.remove(projectName); |
| } |
| persistJob.schedule(persistDelay); |
| } |
| } |
| |
| private static void persist() { |
| synchronized (saveStateMap) { |
| IPath stateLocation = WebPlugin.getDefault().getStateLocation(); |
| java.io.File file = stateLocation.append(WEB_LIBRARIES_CACHE).toFile(); |
| FileOutputStream fOut = null; |
| try { |
| fOut = new FileOutputStream(file); |
| BufferedOutputStream bOut = new BufferedOutputStream(fOut); |
| ObjectOutputStream oOut = new ObjectOutputStream(bOut); |
| oOut.writeObject(saveStateMap); |
| oOut.close(); |
| } catch (FileNotFoundException e) { |
| WebPlugin.logError(e); |
| } catch (IOException e) { |
| WebPlugin.logError(e); |
| } finally { |
| if (fOut != null) { |
| try { |
| fOut.close(); |
| } catch (IOException e) { |
| WebPlugin.logError(e); |
| } |
| } |
| } |
| } |
| } |
| |
| } |