| /** |
| * Copyright (c) 2011, 2014 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany) |
| * 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: |
| * Florian Pirchner - Initial implementation |
| */ |
| package org.eclipse.osbp.vaaclipse.common.ecview; |
| |
| import java.io.File; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.net.URISyntaxException; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.List; |
| import java.util.Map; |
| |
| import javax.inject.Inject; |
| import javax.inject.Named; |
| |
| import org.eclipse.core.runtime.URIUtil; |
| import org.eclipse.e4.core.contexts.IEclipseContext; |
| import org.eclipse.e4.core.di.annotations.Optional; |
| import org.eclipse.e4.ui.internal.workbench.E4Workbench; |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.EStructuralFeature; |
| import org.eclipse.emf.ecore.EStructuralFeature.Setting; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.emf.ecore.resource.ResourceSet; |
| import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; |
| import org.eclipse.emf.ecore.util.EcoreUtil; |
| import org.eclipse.emf.ecore.xmi.XMIResource; |
| import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl; |
| import org.eclipse.osbp.ecview.core.common.extender.IECViewCache; |
| import org.eclipse.osbp.ecview.core.common.model.core.YView; |
| import org.eclipse.osbp.ecview.core.common.store.IViewStore; |
| import org.eclipse.osgi.service.datalocation.Location; |
| |
| @SuppressWarnings("restriction") |
| public class ViewStore implements IViewStore { |
| |
| @Inject |
| IEclipseContext context; |
| |
| @Inject |
| @Optional |
| @Named(E4Workbench.INSTANCE_LOCATION) |
| private Location instanceLocation; |
| |
| @Override |
| public YView getMostRecentView(String userId, String id) { |
| List<YView> views = getAllViewVersions(userId, id); |
| if (!views.isEmpty()) { |
| return views.get(views.size() - 1); |
| } |
| |
| IECViewCache service = context.get(IECViewCache.class); |
| if (service != null) { |
| YView view = service.getView(id); |
| if (view != null) { |
| return EcoreUtil.copy(view); |
| } |
| } |
| |
| return null; |
| } |
| |
| public List<YView> getAllViewVersions(String userId, String id) { |
| ResourceSet rs = new ResourceSetImpl(); |
| List<YView> views = new ArrayList<YView>(); |
| File viewFolder = getUserFolderLocation(userId); |
| File[] files = viewFolder.listFiles(); |
| if (files != null) { |
| for (File file : viewFolder.listFiles()) { |
| if (file.isFile() && file.toString().endsWith(".ecview") |
| && file.toString().contains(id)) { |
| Resource resource = rs.getResource( |
| URI.createFileURI(file.getAbsolutePath()), true); |
| views.add((YView) resource.getContents().get(0)); |
| } |
| } |
| Collections.sort(views, new VersionComparator()); |
| } |
| |
| return views; |
| } |
| |
| private URI getExportViewURI(String folderPath, String id, String version) { |
| File viewFile = new File(folderPath, id + "_" + version + ".ecview"); //$NON-NLS-1$ |
| URI viewURI = URI.createFileURI(viewFile.getAbsolutePath()); |
| return viewURI; |
| } |
| |
| private URI getViewURI(String userId, String id, String version) { |
| File viewFile = new File(getUserFolderLocation(userId), id |
| + "_" + version + ".ecview"); //$NON-NLS-1$ |
| URI viewURI = URI.createFileURI(viewFile.getAbsolutePath()); |
| return viewURI; |
| } |
| |
| private File getUserFolderLocation(String userId) { |
| File location = getBaseLocation(); |
| location = new File(location, userId); //$NON-NLS-1$ |
| return location; |
| } |
| |
| private File getBaseLocation() { |
| File baseLocation; |
| try { |
| baseLocation = new File(URIUtil.toURI(instanceLocation.getURL())); |
| } catch (URISyntaxException e) { |
| throw new RuntimeException(e); |
| } |
| baseLocation = new File(baseLocation, ".metadata"); //$NON-NLS-1$ |
| baseLocation = new File(baseLocation, ".plugins"); //$NON-NLS-1$ |
| baseLocation = new File(baseLocation, "org.eclipse.osbp.ecview"); //$NON-NLS-1$ |
| return baseLocation; |
| } |
| |
| @Override |
| public void saveView(String userId, YView yView) { |
| |
| cleanUp(yView); |
| |
| String id = yView.getId(); |
| URI viewURI = getViewURI(userId, id, toVersion(yView)); |
| try { |
| XMIResource resource = new XMIResourceImpl(viewURI); |
| resource.load(null); |
| resource.getContents().clear(); |
| resource.getContents().add(yView); |
| |
| resource.save(null); |
| |
| } catch (IOException e) { |
| XMIResource resource = new XMIResourceImpl(viewURI); |
| resource.getContents().add(yView); |
| try { |
| resource.save(null); |
| } catch (IOException e1) { |
| throw new RuntimeException(e1); |
| } |
| } |
| } |
| |
| @Override |
| public void export(YView yView, String folder, boolean generateDialog) { |
| |
| cleanUp(yView); |
| |
| String id = yView.getId(); |
| URI viewURI = getExportViewURI(folder, id, toVersion(yView)); |
| try { |
| XMIResource resource = new XMIResourceImpl(viewURI); |
| resource.load(null); |
| resource.getContents().clear(); |
| resource.getContents().add(yView); |
| |
| resource.save(null); |
| |
| } catch (IOException e) { |
| XMIResource resource = new XMIResourceImpl(viewURI); |
| resource.getContents().add(yView); |
| try { |
| resource.save(null); |
| } catch (IOException e1) { |
| throw new RuntimeException(e1); |
| } |
| } |
| |
| if (generateDialog) { |
| generateDialog(yView, folder); |
| } |
| |
| } |
| |
| /** |
| * Generates a dialog dsl model file to be used with the specified ecview. |
| * |
| * @param yView |
| * @param folder |
| */ |
| protected void generateDialog(YView yView, String folderPath) { |
| String dialogContent = "package {package} {\n" |
| + "\tdialog {viewName} ecview \"{viewId}\"\n" + "}"; |
| dialogContent = dialogContent.replace("{package}", toPackageName(yView)); |
| dialogContent = dialogContent.replace("{viewName}", toViewName(yView)); |
| dialogContent = dialogContent.replace("{viewId}", toViewId(yView)); |
| |
| File file = new File(getExportViewURI(folderPath, yView.getId(), |
| toVersion(yView)).appendFileExtension("dialog").toFileString()); |
| FileOutputStream fos = null; |
| try { |
| fos = new FileOutputStream(file); |
| fos.write(dialogContent.getBytes()); |
| } catch (IOException e) { |
| |
| } finally { |
| if (fos != null) { |
| try { |
| fos.close(); |
| } catch (IOException e) { |
| // nothing to do |
| } |
| } |
| } |
| |
| } |
| |
| private CharSequence toViewId(YView yView) { |
| return yView.getViewName(); |
| } |
| |
| private CharSequence toViewName(YView yView) { |
| String name = yView.getViewName(); |
| if (name == null || name.equals("")) { |
| return "DefineMe"; |
| } |
| return name.contains(".") ? name.substring(name.lastIndexOf(".") + 1) |
| : name; |
| } |
| |
| private CharSequence toPackageName(YView yView) { |
| String name = yView.getViewName(); |
| if (name == null || name.equals("") || !name.contains(".")) { |
| return "to.be.defined"; |
| } |
| |
| return name.substring(0, name.lastIndexOf(".")); |
| } |
| |
| @Override |
| public void deleteView(String userId, String id, String version) { |
| URI viewURI = getViewURI(userId, id, version); |
| try { |
| XMIResource resource = new XMIResourceImpl(viewURI); |
| resource.load(null); |
| resource.delete(null); |
| } catch (IOException e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| /** |
| * Remove orphan references. |
| * |
| * @param yView |
| */ |
| private void cleanUp(YView yView) { |
| |
| boolean dummyResource = false; |
| Resource resource = yView.eResource(); |
| if (resource == null) { |
| dummyResource = true; |
| resource = new XMIResourceImpl( |
| URI.createURI("/toDetectOrphanedEObjects")); |
| resource.getContents().add(yView); |
| } |
| |
| while (true) { |
| boolean orphanFound = false; |
| Map<EObject, Collection<Setting>> crossReferences = EcoreUtil.CrossReferencer |
| .find(Collections.singletonList(yView)); |
| for (Map.Entry<EObject, Collection<Setting>> entry : crossReferences |
| .entrySet()) { |
| EObject orphan = entry.getKey(); |
| if (orphan.eResource() == null) { |
| orphanFound = true; |
| Collection<Setting> settings = entry.getValue(); |
| for (Setting setting : settings) { |
| EObject container = setting.getEObject(); |
| EStructuralFeature containingFeature = setting |
| .getEStructuralFeature(); |
| // if the feature is required, then the target is not |
| // prop configured anymore. |
| // so we also remove the target from its parent |
| EcoreUtil.remove(setting, orphan); |
| if (!containingFeature.isMany() |
| && containingFeature.isRequired()) { |
| // remove the container from its parent |
| removeFromContainer(container); |
| } |
| } |
| } |
| } |
| if (!orphanFound) { |
| break; |
| } |
| } |
| if (dummyResource) { |
| resource.getContents().clear(); |
| } |
| } |
| |
| /** |
| * Removes the given object from its container. And iterates to the most top |
| * feature, which is not required anymore. |
| * |
| * @param object |
| */ |
| private void removeFromContainer(EObject object) { |
| EStructuralFeature feature = object.eContainingFeature(); |
| EObject container = object.eContainer(); |
| EcoreUtil.remove(object); |
| |
| if (container != null && !feature.isMany() && feature.isRequired()) { |
| // remove the container from its parent |
| removeFromContainer(container); |
| } |
| } |
| |
| private String toVersion(YView yView) { |
| String version = yView.getVersion() != null ? yView.getVersion() |
| : "0.0.0"; |
| |
| if (!version.equals(yView.getVersion())) { |
| yView.setVersion(version); |
| } |
| return version; |
| } |
| |
| private static class VersionComparator implements Comparator<YView> { |
| @Override |
| public int compare(YView o1, YView o2) { |
| if (o1.getVersion() == null) { |
| if (o2.getVersion() == null) { |
| return 0; |
| } else { |
| return 1; |
| } |
| } |
| return o1.getVersion().compareTo(o2.getVersion()); |
| } |
| } |
| } |