/** * Copyright (c) 2013-2016 Angelo ZERR. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation */ package tern.eclipse.ide.internal.core; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import tern.EcmaVersion; import tern.TernException; import tern.eclipse.ide.core.IIDETernProject; import tern.eclipse.ide.core.IWorkingCopy; import tern.eclipse.ide.core.IWorkingCopyListener; import tern.eclipse.ide.core.TernCorePlugin; import tern.metadata.TernModuleMetadata; import tern.repository.ITernRepository; import tern.server.ITernModule; import tern.server.TernDef; import tern.server.TernPlugin; import tern.utils.TernModuleHelper; /** * Working copy implementation. */ public class WorkingCopy implements IWorkingCopy { private final IIDETernProject project; private final List<IWorkingCopyListener> listeners; private final List<Object> callers; private List<ITernModule> checkedModules; private List<ITernModule> workingCopyModules; private EcmaVersion ecmaVersion; private List<ITernModule> filteredModules; public WorkingCopy(IIDETernProject project) { this.project = project; this.callers = new ArrayList<Object>(); this.listeners = new ArrayList<IWorkingCopyListener>(); } public void initialize() throws TernException { clear(); // Get local and global tern modules List<ITernModule> allModules = project.getAllModules(); // Group by type workingCopyModules = TernModuleHelper.groupByType(allModules); // Filtered modules filteredModules = new ArrayList<ITernModule>(); for (ITernModule module : workingCopyModules) { if (!(isIgnoreModule(module, TernDef.ecmascript.getType()) || isIgnoreModule(module, TernPlugin.es_modules.getType()) || isIgnoreModule(module, TernPlugin.doc_comment.getType()))) { filteredModules.add(module); } } // checked modules List<ITernModule> checkedModules = new WorkingCopyModuleList(this, TernCorePlugin.getTernRepositoryManager().getCheckedModules(project, workingCopyModules)); this.setCheckedModules(checkedModules); setEcmaVersion(project.getEcmaVersion()); } private boolean isIgnoreModule(ITernModule module, String type) { return type.equals(module.getType()); } public List<ITernModule> getCheckedModules() { return checkedModules; } private void setCheckedModules(List<ITernModule> checkedModules) { this.checkedModules = checkedModules; } @Override public void call(Object caller) { if (!callers.contains(caller)) { callers.add(caller); } } @Override public boolean isDirty() { return callers.size() == 0; } @Override public void commit(Object caller) throws IOException { removeCaller(caller); if (isDirty()) { try { // save tern project with updated tern modules ITernRepository repository = project.getRepository(); // clear Plugin + JSON Type Definition project.clearPlugins(); project.clearLibs(); // Add Plugin + JSON Type Definition Collection<String> requiredDependencies = null; ITernModule dependencyModule = null; List<ITernModule> sortedModules = new ArrayList<ITernModule>(); for (ITernModule module : this.getCheckedModules()) { TernModuleMetadata metadata = module.getMetadata(); if (metadata != null) { // add required dependencies (ex : if ecma6 is checked, // ecma5 must // be added too). requiredDependencies = metadata.getRequiredDependencies(module.getVersion()); for (String dependency : requiredDependencies) { dependencyModule = repository.getModule(dependency); if (dependencyModule != null && !sortedModules.contains(dependencyModule)) { sortedModules.add(dependencyModule); } } } if (module != null && !sortedModules.contains(module)) { sortedModules.add(module); } } TernModuleHelper.sort(sortedModules); for (ITernModule m : sortedModules) { TernModuleHelper.update(m, project); } if (ecmaVersion != null) { project.setEcmaVersion(ecmaVersion); } project.save(); } finally { clear(); } } } @Override public void clear() { this.callers.clear(); this.listeners.clear(); if (checkedModules != null) { checkedModules.clear(); } } private void removeCaller(Object caller) { callers.remove(caller); } public boolean hasCheckedTernModule(String moduleName) { for (ITernModule checkedModule : checkedModules) { if (moduleName.equals(checkedModule.getName())) { return true; } } return false; } public ITernModule getTernModule(String moduleName) throws TernException { for (ITernModule module : workingCopyModules) { if (moduleName.equals(module.getName())) { return module; } } return null; } public void addWorkingCopyListener(IWorkingCopyListener listener) { synchronized (listener) { if (!listeners.contains(listener)) { listeners.add(listener); } } } public void removeWorkingCopyListener(IWorkingCopyListener listener) { synchronized (listener) { listeners.remove(listener); } } void fireSelectionModules(ITernModule module, boolean selected) { synchronized (listeners) { for (IWorkingCopyListener listener : listeners) { listener.moduleSelectionChanged(module, selected); } } } public List<ITernModule> getAllModules() { return workingCopyModules; } @Override public List<ITernModule> getFilteredModules() { return filteredModules; } @Override public IIDETernProject getProject() { return project; } @Override public void setEcmaVersion(EcmaVersion ecmaVersion) { this.ecmaVersion = ecmaVersion; } @Override public EcmaVersion getEcmaVersion() { return ecmaVersion; } }