/** * author: Marcel Genzmehr * 19.08.2011 */ package org.docear.plugin.core; import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.TreeMap; import java.util.Vector; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.docear.plugin.core.event.DocearEvent; import org.docear.plugin.core.event.DocearEventType; import org.docear.plugin.core.event.IDocearEventListener; import org.docear.plugin.core.features.DocearProgressObserver; import org.docear.plugin.core.io.IOTools; import org.docear.plugin.core.logger.DocearEventLogger; import org.freeplane.core.resources.ResourceController; import org.freeplane.core.util.LogUtils; import org.freeplane.features.mode.Controller; import org.freeplane.plugin.workspace.WorkspaceController; import org.freeplane.plugin.workspace.WorkspaceUtils; /** * */ public class DocearController implements IDocearEventListener { private final static String PLACEHOLDER_PROFILENAME = "@@PROFILENAME@@"; private static final String DEFAULT_LIBRARY_PATH = "workspace:/"+PLACEHOLDER_PROFILENAME+"/library"; private final static Pattern PATTERN = Pattern.compile(PLACEHOLDER_PROFILENAME); static final String DOCEAR_FIRST_RUN_PROPERTY = "docear.already_initialized"; private final static String DOCEAR_VERSION_NUMBER = "docear.version.number"; private String applicationName; private String applicationVersion; private String applicationStatus; private String applicationStatusVersion; private int applicationBuildNumber; private String applicationBuildDate; private final SemaphoreController semaphoreController = new SemaphoreController(); private final DocearEventLogger docearEventLogger = new DocearEventLogger(); private final Vector<IDocearEventListener> docearListeners = new Vector<IDocearEventListener>(); private final static DocearController docearController = new DocearController(); private IDocearLibrary currentLibrary = null; private final Set<String> workingThreads = new HashSet<String>(); private final boolean firstRun; private boolean applicationShutdownAborted = false; private Map<Class<?>, Set<DocearProgressObserver>> progressObservers = new TreeMap<Class<?>, Set<DocearProgressObserver>>(new Comparator<Class<?>>() { public int compare(Class<?> c1, Class<?> c2) { if(c1.equals(c2)) { return 0; } return c1.getName().compareTo(c2.getName()); } }); /*********************************************************************************** * CONSTRUCTORS **********************************************************************************/ protected DocearController() { firstRun = !ResourceController.getResourceController().getBooleanProperty(DOCEAR_FIRST_RUN_PROPERTY); setApplicationIdentifiers(); addDocearEventListener(this); } /*********************************************************************************** * METHODS **********************************************************************************/ public boolean isDocearFirstStart() { return firstRun; } public boolean isLicenseDialogNecessary() { int storedBuildNumber = Integer.parseInt(ResourceController.getResourceController().getProperty(DOCEAR_VERSION_NUMBER, "0")); if (storedBuildNumber == 0) { ResourceController.getResourceController().setProperty(DOCEAR_VERSION_NUMBER, ""+this.applicationBuildNumber); return true; } else { return false; } } public static DocearController getController() { return docearController; } public void addWorkingThreadHandle(String handleId) { if(handleId == null) { return; } synchronized (workingThreads) { workingThreads.add(handleId); } } public void removeWorkingThreadHandle(String handleId) { if(handleId == null) { return; } synchronized (workingThreads) { workingThreads.remove(handleId); } } public void setApplicationIdentifiers() { final Properties versionProperties = new Properties(); InputStream in = null; try { in = this.getClass().getResource("/version.properties").openStream(); versionProperties.load(in); } catch (final IOException e) { } final Properties buildProperties = new Properties(); in = null; try { in = this.getClass().getResource("/build.number").openStream(); buildProperties.load(in); } catch (final IOException e) { } setApplicationName("Docear"); setApplicationVersion(versionProperties.getProperty("docear_version")); setApplicationStatus(versionProperties.getProperty("docear_version_status")); setApplicationStatusVersion(versionProperties.getProperty("docear_version_status_number")); setApplicationBuildDate(versionProperties.getProperty("build_date")); setApplicationBuildNumber(Integer.parseInt(buildProperties.getProperty("build.number")) -1); } public Version getVersion() { try { DocearController docearController = DocearController.getController(); Version version = new Version(); String[] versionStrings = docearController.getApplicationVersion().split("\\."); version.setMajorVersion(Integer.parseInt(versionStrings[0])); version.setMiddleVersion(Integer.parseInt(versionStrings[1])); version.setMinorVersion(Integer.parseInt(versionStrings[2])); version.setStatus(docearController.getApplicationStatus()); version.setStatusNumber(Integer.parseInt(docearController.getApplicationStatusVersion())); version.setBuildNumber(docearController.getApplicationBuildNumber()); return version; } catch(Exception e) { LogUtils.warn(e); return null; } } public void addDocearEventListener(IDocearEventListener listener) { if(this.docearListeners.contains(listener)) { return; } this.docearListeners.add(listener); } public void removeDocearEventListener(IDocearEventListener listener) { this.docearListeners.remove(listener); } public void removeAllDocearEventListeners() { this.docearListeners.removeAllElements(); } public void dispatchDocearEvent(DocearEvent event) { //LogUtils.info("DOCEAR: dispatchEvent: "+ event); for(IDocearEventListener listener : this.docearListeners) { listener.handleEvent(event); } } public IDocearLibrary getLibrary() { return currentLibrary; } public URI getLibraryPath() { Matcher mainMatcher = PATTERN.matcher(DEFAULT_LIBRARY_PATH); String ret = mainMatcher.replaceAll(WorkspaceController.getController().getPreferences().getWorkspaceProfileHome()); return WorkspaceUtils.absoluteURI(URI.create(ret)); } public DocearEventLogger getDocearEventLogger() { return this.docearEventLogger; } // public String getApplicationVersion() { // String version = ResourceController.getResourceController().getProperty("docear_version"); // String status = ResourceController.getResourceController().getProperty("docear_status"); // // return version+" "+status; // } public String getApplicationName() { return this.applicationName; } public void setApplicationName(String applicationName) { this.applicationName = applicationName; } public String getApplicationVersion() { return applicationVersion; } private void setApplicationVersion(String applicationVersion) { this.applicationVersion = applicationVersion; } public String getApplicationStatus() { return applicationStatus; } private void setApplicationStatus(String applicationStatus) { this.applicationStatus = applicationStatus; } public String getApplicationStatusVersion() { return applicationStatusVersion; } private void setApplicationStatusVersion(String applicationStatusVersion) { this.applicationStatusVersion = applicationStatusVersion; } public int getApplicationBuildNumber() { return applicationBuildNumber; } private void setApplicationBuildNumber(int i) { this.applicationBuildNumber = i; } public String getApplicationBuildDate() { return applicationBuildDate; } private void setApplicationBuildDate(String applicationBuildDate) { this.applicationBuildDate = applicationBuildDate; } private boolean hasWorkingThreads() { synchronized (workingThreads) { return !workingThreads.isEmpty(); } } public boolean shutdown() { dispatchDocearEvent(new DocearEvent(this, DocearEventType.APPLICATION_CLOSING)); Controller.getCurrentController().getViewController().saveProperties(); ResourceController.getResourceController().saveProperties(); if(!waitThreadsReady()){ return false; } if(Controller.getCurrentController().getViewController().quit()) { dispatchDocearEvent(new DocearEvent(this, DocearEventType.FINISH_THREADS)); if(!waitThreadsReady()){ return false; } } else { return false; } return true; } public void addProgressObserver(Class<?> clazz, DocearProgressObserver observer) { Set<DocearProgressObserver> observers = progressObservers.get(clazz); if(observers == null) { observers = new HashSet<DocearProgressObserver>(); progressObservers.put(clazz, observers); } observers.add(observer); } public Collection<DocearProgressObserver> getProgressObservers(Class<?> clazz) { Collection<DocearProgressObserver> observers = progressObservers.get(clazz); if(observers == null) { observers = Collections.emptySet(); } return observers; } private boolean waitThreadsReady() { while(hasWorkingThreads()) { try { Thread.sleep(100); } catch (InterruptedException e1) { } } if(this.applicationShutdownAborted){ this.applicationShutdownAborted = false; return false; } return true; } public String getDataProcessingTerms() { try { return IOTools.getStringFromStream(DocearController.class.getResourceAsStream("/Docear_data_processing.txt"),"UTF-8"); } catch (IOException e) { LogUtils.warn(e); return "Data Processing"; } } public String getDataPrivacyTerms() { try { return IOTools.getStringFromStream(DocearController.class.getResourceAsStream("/Docear_data_privacy.txt"), "UTF-8"); } catch (IOException e) { LogUtils.warn(e); return "Data Privacy"; } } public String getTermsOfUse() { try { return IOTools.getStringFromStream(DocearController.class.getResourceAsStream("/Docear_terms_of_use.txt"),"UTF-8"); } catch (IOException e) { LogUtils.warn(e); return "Terms of Use"; } } /*********************************************************************************** * REQUIRED METHODS FOR INTERFACES **********************************************************************************/ public void handleEvent(DocearEvent event) { if(event.getType() == DocearEventType.APPLICATION_CLOSING) { WorkspaceUtils.saveCurrentConfiguration(); } else if(event.getType() == DocearEventType.APPLICATION_CLOSING_ABORTED){ this.applicationShutdownAborted = true; } else if(event.getType() == DocearEventType.NEW_LIBRARY && event.getSource() instanceof IDocearLibrary) { this.currentLibrary = (IDocearLibrary) event.getSource(); LogUtils.info("DOCEAR: new DocearLibrary set"); } } public SemaphoreController getSemaphoreController() { return semaphoreController; } }