| package org.eclipse.jst.j2ee.internal.common.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.util.HashMap; |
| import java.util.Iterator; |
| 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.SafeRunner; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.jobs.Job; |
| import org.eclipse.jst.j2ee.internal.common.classpath.J2EEComponentClasspathContainer.LastUpdate; |
| import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin; |
| |
| public class J2EEComponentClasspathContainerStore { |
| private static final String EAR_LIBRARIES_CACHE = "earLibrariesCache.index"; //$NON-NLS-1$ |
| private static Map<String, LastUpdate> restoreStateMap; |
| private static Map<String, LastUpdate> saveStateMap = new HashMap<String, LastUpdate>(); |
| |
| static { |
| IPath stateLocation = J2EEPlugin.getDefault().getStateLocation(); |
| java.io.File file = stateLocation.append(EAR_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, LastUpdate>) 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, LastUpdate>> iterator = restoreStateMap.entrySet().iterator(); |
| while(iterator.hasNext()){ |
| Entry<String, LastUpdate> next = iterator.next(); |
| String s = next.getKey(); |
| LastUpdate lu = next.getValue(); |
| if(s == null || lu == null){ |
| //may throw ClassCastException |
| } |
| } |
| deleteCache = false; |
| } catch (FileNotFoundException e) { |
| J2EEPlugin.logError(e); |
| } catch (IOException e) { |
| J2EEPlugin.logError(e); |
| } catch (ClassNotFoundException e) { |
| J2EEPlugin.logError(e); |
| } catch (ClassCastException e){ |
| J2EEPlugin.logError(e); |
| } |
| finally { |
| if (fIn != null) { |
| try { |
| fIn.close(); |
| } catch (IOException e) { |
| J2EEPlugin.logError(e); |
| } |
| } |
| if(deleteCache){ |
| restoreStateMap = new HashMap<String, LastUpdate>(); |
| file.delete(); |
| } |
| } |
| } |
| } catch (Throwable e){ |
| try{ |
| J2EEPlugin.logError(e); |
| file.delete(); |
| } catch (Exception e2){ |
| //eat it |
| } |
| restoreStateMap = new HashMap<String, LastUpdate>(); |
| } finally { |
| if (restoreStateMap == null) { |
| restoreStateMap = new HashMap<String, LastUpdate>(); |
| } |
| } |
| } |
| |
| private static void persist() { |
| synchronized (saveStateMap) { |
| IPath stateLocation = J2EEPlugin.getDefault().getStateLocation(); |
| java.io.File file = stateLocation.append(EAR_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) { |
| J2EEPlugin.logError(e); |
| } catch (IOException e) { |
| J2EEPlugin.logError(e); |
| } finally { |
| if (fOut != null) { |
| try { |
| fOut.close(); |
| } catch (IOException e) { |
| J2EEPlugin.logError(e); |
| } |
| } |
| } |
| } |
| } |
| |
| static void flush(String projectName) { |
| synchronized (restoreStateMap) { |
| restoreStateMap.remove(projectName); |
| } |
| synchronized (saveStateMap) { |
| saveStateMap.remove(projectName); |
| } |
| } |
| |
| static void flushAll() { |
| synchronized (restoreStateMap) { |
| restoreStateMap.clear(); |
| } |
| synchronized (saveStateMap) { |
| saveStateMap.clear(); |
| } |
| IPath stateLocation = J2EEPlugin.getDefault().getStateLocation(); |
| java.io.File file = stateLocation.append(EAR_LIBRARIES_CACHE).toFile(); |
| file.delete(); |
| } |
| |
| static LastUpdate getRestoreState(String projectName) { |
| LastUpdate lastUpdate = null; |
| synchronized (restoreStateMap) { |
| lastUpdate = restoreStateMap.get(projectName); |
| } |
| if (lastUpdate != null) { |
| synchronized (saveStateMap) { |
| saveStateMap.put(projectName, lastUpdate); |
| } |
| } |
| return lastUpdate; |
| } |
| |
| private static class PersistJob extends Job { |
| |
| public PersistJob() { |
| super("Persist EAR 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) { |
| J2EEPlugin.logError(exception); |
| } |
| }); |
| return Status.OK_STATUS; |
| } |
| } |
| |
| private static int persistDelay = 60000; // 1 minute |
| private static PersistJob persistJob = new PersistJob(); |
| |
| static void saveState(String projectName, LastUpdate lastUpdate) { |
| boolean scheduleJob = false; |
| synchronized (saveStateMap) { |
| LastUpdate previousUpdate = saveStateMap.get(projectName); |
| //this check is to avoid I/O if possible |
| if(null == previousUpdate || !previousUpdate.equals(lastUpdate)){ |
| saveStateMap.put(projectName, lastUpdate); |
| scheduleJob = true; |
| } |
| } |
| if(scheduleJob){ |
| synchronized (restoreStateMap) { |
| //if it changed, do not load it from the cache again |
| restoreStateMap.remove(projectName); |
| } |
| persistJob.schedule(persistDelay); |
| } |
| } |
| |
| } |