diff --git a/plugins/org.dslforge.texteditor.demo/RAP Text Editor Demo.launch b/plugins/org.dslforge.texteditor.demo/RAP Text Editor Demo.launch index b1fc2ea..4843abf 100644 --- a/plugins/org.dslforge.texteditor.demo/RAP Text Editor Demo.launch +++ b/plugins/org.dslforge.texteditor.demo/RAP Text Editor Demo.launch @@ -32,10 +32,10 @@ - + - + diff --git a/plugins/org.dslforge.workspace/META-INF/MANIFEST.MF b/plugins/org.dslforge.workspace/META-INF/MANIFEST.MF index 34cf40f..39b3290 100644 --- a/plugins/org.dslforge.workspace/META-INF/MANIFEST.MF +++ b/plugins/org.dslforge.workspace/META-INF/MANIFEST.MF @@ -11,6 +11,7 @@ Require-Bundle: org.eclipse.core.runtime, Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Export-Package: org.dslforge.database.pu.tables, org.dslforge.workspace, + org.dslforge.workspace.contribution, org.dslforge.workspace.internal Import-Package: javax.persistence;version="2.1.0", org.apache.log4j;version="1.2.15", diff --git a/plugins/org.dslforge.workspace/build.properties b/plugins/org.dslforge.workspace/build.properties index 8b3e71b..cc20384 100644 --- a/plugins/org.dslforge.workspace/build.properties +++ b/plugins/org.dslforge.workspace/build.properties @@ -5,4 +5,5 @@ bin.includes = META-INF/,\ icons/,\ lib/derby.jar,\ plugin.xml,\ - about.html + about.html,\ + schema/ diff --git a/plugins/org.dslforge.workspace/schema/configuration.exsd b/plugins/org.dslforge.workspace/schema/configuration.exsd index 47c68ab..7cfaaac 100644 --- a/plugins/org.dslforge.workspace/schema/configuration.exsd +++ b/plugins/org.dslforge.workspace/schema/configuration.exsd @@ -17,6 +17,9 @@ + + + @@ -44,6 +47,23 @@ + + + + A workspace contribution to the text editor workbench. + + + + + + + The root path of the workspace, e.g. D:/www/dslforge/workspace or /var/lib/tomcat7/workspace + + + + + + diff --git a/plugins/org.dslforge.workspace/src/org/dslforge/workspace/IWorkspaceConstants.java b/plugins/org.dslforge.workspace/src/org/dslforge/workspace/IWorkspaceConstants.java index e6fc13a..00597b0 100644 --- a/plugins/org.dslforge.workspace/src/org/dslforge/workspace/IWorkspaceConstants.java +++ b/plugins/org.dslforge.workspace/src/org/dslforge/workspace/IWorkspaceConstants.java @@ -26,4 +26,5 @@ public interface IWorkspaceConstants { public static final String PATH_SEPARATOR = "\\"; public static final String LOCKED = "locked"; public static final String UNLOCKED = "unlocked"; + public static final String WORKSPACE_DEFAULT_PATH = "D:/www/dslforge/workspace"; } diff --git a/plugins/org.dslforge.workspace/src/org/dslforge/workspace/WorkspaceManager.java b/plugins/org.dslforge.workspace/src/org/dslforge/workspace/WorkspaceManager.java index 89b4b9c..329eb56 100644 --- a/plugins/org.dslforge.workspace/src/org/dslforge/workspace/WorkspaceManager.java +++ b/plugins/org.dslforge.workspace/src/org/dslforge/workspace/WorkspaceManager.java @@ -1,7 +1,7 @@ /** * * - * Copyright (c) 2015 PlugBee. All rights reserved. + * Copyright (c) 2016 PlugBee. All rights reserved. * * This program and the accompanying materials are made available * under the terms of the Eclipse Public License v1.0 which @@ -30,6 +30,8 @@ import org.dslforge.database.pu.tables.Resource; import org.dslforge.database.pu.tables.User; import org.dslforge.workspace.internal.DatabaseService; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; import org.eclipse.emf.common.util.URI; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.rap.rwt.RWT; @@ -45,7 +47,7 @@ public class WorkspaceManager { private WorkspaceManager() { setupWorkspace(); } - + private void setupWorkspace() { EntityManagerFactory emf = DatabaseService.getInstance().getEmf(); Map properties = emf.getProperties(); @@ -90,31 +92,30 @@ private String computeResourceName(URI absoluteURI) { } private String computeRelativePath(URI absoluteURI) { - URI rootURI = URI.createFileURI(getWorkspaceRoot()); - URI relativeURI = absoluteURI.deresolve(rootURI); - String[] segments = relativeURI.segments(); + IPath absolutePath = new Path(absoluteURI.devicePath()); + IPath relativePath = absolutePath.makeRelativeTo(new Path(getWorkspaceRoot())); + String[] segments = relativePath.segments(); if (segments.length == 0) { throw new RuntimeException("Problem when computing relative path for " + absoluteURI); } - return relativeURI.toString(); + return relativePath.toString(); } private String computeProjectName(URI absoluteURI) { - URI rootURI = URI.createFileURI(getWorkspaceRoot()); - URI relativeURI = absoluteURI.deresolve(rootURI); - String[] segments = relativeURI.segments(); + IPath absolutePath = new Path(absoluteURI.devicePath()); + IPath relativePath = absolutePath.makeRelativeTo(new Path(getWorkspaceRoot())); + String[] segments = relativePath.segments(); if (segments.length == 0) { throw new RuntimeException("Problem when computing relative path for " + absoluteURI); } - String projectName = relativeURI.segment(0); - return projectName; + return relativePath.segment(0); } public void createProject(String projectName, String description, String visibility) { String userId = (String) RWT.getUISession().getAttribute("user"); String workspaceRoot = getWorkspaceRoot(); - String projectPath = workspaceRoot + projectName; - final File file = new File(projectPath); + IPath projectPath = new Path(workspaceRoot).addTrailingSeparator().append(projectName); + final File file = projectPath.toFile(); if (!file.exists()) { createProject(projectName, description, projectName, userId, visibility); Display.getCurrent().syncExec(new Runnable() { @@ -133,7 +134,10 @@ private void createProject(String projectName, String description, String path, } public boolean isProject(File file) { - return (file.isDirectory() && file.getParent() != null && file.getParent().equals(getWorkspaceRoot())); + String parent = file.getParent(); + boolean result = new Path(parent).equals(new Path(getWorkspaceRoot())); + return (file.isDirectory() && parent != null && result); + } public void deleteProject(final File file) { @@ -217,14 +221,14 @@ private boolean deleteProject(String projectName) { return false; } try { - // delete files in the porject + // delete files in the project List allResourcesInProject = DatabaseService.getInstance().getAllResourcesInProject(projectName); for (Resource r : allResourcesInProject) { final String filePath = getWorkspaceRoot() + r.getPath().replace("/", "\\"); final File file = new File(filePath); if (file.exists()) { if (!isLocked(file)) { - WorkspaceManager.INSTANCE.deleteResource(projectName, r.getPath()); + deleteResource(projectName, r.getPath()); String userId = (String) RWT.getUISession().getAttribute("user"); logger.info(userId + " deleted file " + file.getPath()); } else { @@ -242,7 +246,7 @@ private boolean deleteProject(String projectName) { final File file = new File(filePath); if (file.exists()) { if (!isLocked(file)) { - WorkspaceManager.INSTANCE.deleteFolder(folder.getPath()); + deleteFolder(folder.getPath()); } } } @@ -250,7 +254,7 @@ private boolean deleteProject(String projectName) { DatabaseService.getInstance().deleteProject(projectName); } catch (PersistenceException ex) { - // TODO: project contains resources, should make sure to delete all + //project contains resources, should make sure to delete all // the resources inside the project. MessageDialog.openInformation(null, "Unexpected Error", "Project " + projectName + " could not be deleted, check your user access privileges."); diff --git a/plugins/org.dslforge.workspace/src/org/dslforge/workspace/contribution/IWorkspaceContribution.java b/plugins/org.dslforge.workspace/src/org/dslforge/workspace/contribution/IWorkspaceContribution.java new file mode 100644 index 0000000..499487f --- /dev/null +++ b/plugins/org.dslforge.workspace/src/org/dslforge/workspace/contribution/IWorkspaceContribution.java @@ -0,0 +1,30 @@ +/** + * + * + * Copyright (c) 2016 PlugBee. 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: + * Amine Lajmi - Initial API and implementation + * + * + */ +package org.dslforge.workspace.contribution; + +import org.eclipse.core.runtime.IPath; + +public interface IWorkspaceContribution { + + /** + * Retursn the workspace root path declared in + * org.dslforge.workspace.configuration extension. For example e.g. + * D:/www/dslforge/workspace (windows) or /var/lib/tomcat/workspace (linux) + * + * @return the workspace root path + */ + IPath getWorkspaceRootPath(); +} diff --git a/plugins/org.dslforge.workspace/src/org/dslforge/workspace/contribution/WorkspaceContribution.java b/plugins/org.dslforge.workspace/src/org/dslforge/workspace/contribution/WorkspaceContribution.java new file mode 100644 index 0000000..0ec1e66 --- /dev/null +++ b/plugins/org.dslforge.workspace/src/org/dslforge/workspace/contribution/WorkspaceContribution.java @@ -0,0 +1,33 @@ +/** + * + * + * Copyright (c) 2016 PlugBee. 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: + * Amine Lajmi - Initial API and implementation + * + * + */ +package org.dslforge.workspace.contribution; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +public class WorkspaceContribution implements IWorkspaceContribution { + + private IPath rootPath; + + public WorkspaceContribution(String stringPath) { + rootPath = new Path(stringPath); + } + + @Override + public IPath getWorkspaceRootPath() { + return rootPath; + } +} \ No newline at end of file diff --git a/plugins/org.dslforge.workspace/src/org/dslforge/workspace/internal/Activator.java b/plugins/org.dslforge.workspace/src/org/dslforge/workspace/internal/Activator.java index 3acce8b..a59a24b 100644 --- a/plugins/org.dslforge.workspace/src/org/dslforge/workspace/internal/Activator.java +++ b/plugins/org.dslforge.workspace/src/org/dslforge/workspace/internal/Activator.java @@ -1,7 +1,7 @@ /** * * - * Copyright (c) 2015 PlugBee. All rights reserved. + * Copyright (c) 2016 PlugBee. All rights reserved. * * This program and the accompanying materials are made available * under the terms of the Eclipse Public License v1.0 which @@ -15,13 +15,24 @@ */ package org.dslforge.workspace.internal; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import javax.persistence.EntityManagerFactory; import org.apache.log4j.Logger; import org.dslforge.workspace.IWorkspaceConstants; +import org.dslforge.workspace.contribution.IWorkspaceContribution; +import org.dslforge.workspace.contribution.WorkspaceContribution; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Platform; import org.osgi.framework.Bundle; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; +import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; import org.osgi.service.jpa.EntityManagerFactoryBuilder; import org.osgi.util.tracker.ServiceTracker; @@ -38,14 +49,18 @@ public class Activator implements BundleActivator, ServiceTrackerCustomizer { // The plug-in ID public static final String PLUGIN_ID = "org.dslforge.workspace"; //$NON-NLS-1$ + private static final String WORKSPACE_CONTRIBUTION_EXTENSION_POINT = "org.dslforge.workspace.configuration"; + private static final String WORKSPACE_CONTRIBUTION_CONFIG_ELEMENT = "contribution"; + private static final String WORKSPACE_CONTRIBUTION_PATH = "path"; + // The shared instance private static Activator plugin; private static BundleContext ctx; - private ServiceTracker emfTracker; - - EntityManagerFactory emf; + private EntityManagerFactory emf; + private IPath workspaceRootPath; + private static List workspaceContributions; public static Activator getDefault() { return plugin; @@ -67,7 +82,47 @@ public void start(BundleContext context) throws Exception { emfTracker = new ServiceTracker(ctx, EntityManagerFactory.class.getName(), this); emfTracker.open(); } - + + private void initialize() { + workspaceContributions = new ArrayList(); + if (Platform.isRunning()) { + IConfigurationElement[] configElements =Platform.getExtensionRegistry().getConfigurationElementsFor(WORKSPACE_CONTRIBUTION_EXTENSION_POINT); + if (configElements.length != 0) { + for (IConfigurationElement configElement : configElements) { + try { + if (configElement.getName().toLowerCase().equals(WORKSPACE_CONTRIBUTION_CONFIG_ELEMENT.toLowerCase())) { + String workspaceRootPath = configElement.getAttribute(WORKSPACE_CONTRIBUTION_PATH); + if (workspaceContributions.contains(workspaceRootPath)) { + logger.warn("Duplicate workspace contribution found for: " + workspaceRootPath); + continue; + } + WorkspaceContribution contribution = new WorkspaceContribution(workspaceRootPath); + workspaceContributions.add(contribution); + } + } catch (Exception ex) { + logger.error(ex.getMessage(), ex); + } + } + } + } + else throw new RuntimeException("Platform is not running at this point."); + } + + public IWorkspaceContribution getWorkspaceContribution() { + initialize(); + if (workspaceContributions.size() == 1) { + return workspaceContributions.get(0); + } else { + if (workspaceContributions.isEmpty()) { + // no workspace contributions, ignore + } else if (workspaceContributions.size() > 1) { + logger.error("More than one workspace extension has been registered"); + } + // use default persistence.xml properties + return new WorkspaceContribution(IWorkspaceConstants.WORKSPACE_DEFAULT_PATH); + } + } + @Override public void stop(BundleContext context) throws Exception { logger.info(PLUGIN_ID + " stopping!"); @@ -80,28 +135,39 @@ public void stop(BundleContext context) throws Exception { @SuppressWarnings("unchecked") public Object addingService(ServiceReference ref) { - Bundle b = ref.getBundle(); - final Object service = b.getBundleContext().getService(ref); + IWorkspaceContribution workspaceContribution = getWorkspaceContribution(); + workspaceRootPath = workspaceContribution.getWorkspaceRootPath(); + Bundle bundle = ref.getBundle(); + final Object service = bundle.getBundleContext().getService(ref); String unitName = (String) ref.getProperty(EntityManagerFactoryBuilder.JPA_UNIT_NAME); if (unitName.equals(IWorkspaceConstants.PERSISTENCE_UNIT_NAME)) { - emf = (EntityManagerFactory) service; + EntityManagerFactoryBuilder entityManagerFactoryBuilder = lookupEntityManagerFactoryBuilder(unitName); + emf = entityManagerFactoryBuilder.createEntityManagerFactory(overrideConfiguration()); DatabaseService.getInstance().setEntityManagerFactory(emf); } return service; } - -// public Map defaultProperties() { -// Map props = new HashMap(); -// props.put("javax.persistence.jdbc.driver", IWorkspaceConstants.JDBC_DATABASE_DRIVER); -// props.put("javax.persistence.jdbc.url", IWorkspaceConstants.JDBC_DATABASE_URL); -// props.put("javax.persistence.jdbc.user", IWorkspaceConstants.JDBC_DATABASE_USER); -// props.put("javax.persistence.jdbc.password", IWorkspaceConstants.JDBC_DATABASE_PASSWORD); -// props.put("eclipselink.logging.level", "OFF"); -// props.put(PersistenceUnitProperties.CLASSLOADER, this.getClass().getClassLoader()); -// props.put(PersistenceUnitProperties.WEAVING, "false"); -// return props; -// } - + + private Map overrideConfiguration() { + Map props = new HashMap(); + props.put(IWorkspaceConstants.JAVAX_PERSISTENCE_JDBC_URL, + IWorkspaceConstants.JDBC_PREFIX + workspaceRootPath.removeTrailingSeparator().toString() + + IWorkspaceConstants.METADATA_FOLDER + ";create=true"); + return props; + } + + @SuppressWarnings("unchecked") + public EntityManagerFactoryBuilder lookupEntityManagerFactoryBuilder(String puName) { + String filter = "(osgi.unit.name=" + puName + ")"; + ServiceReference[] refs = null; + try { + refs = ctx.getServiceReferences(EntityManagerFactoryBuilder.class.getName(), filter); + } catch (InvalidSyntaxException isEx) { + new RuntimeException("Found bad filter in manifest file.", isEx); + } + return (refs == null) ? null : (EntityManagerFactoryBuilder) ctx.getService(refs[0]); + } + public void modifiedService(ServiceReference ref, Object service) { } diff --git a/plugins/org.dslforge.workspace/src/org/dslforge/workspace/internal/DatabaseService.java b/plugins/org.dslforge.workspace/src/org/dslforge/workspace/internal/DatabaseService.java index f24ebfd..5713948 100644 --- a/plugins/org.dslforge.workspace/src/org/dslforge/workspace/internal/DatabaseService.java +++ b/plugins/org.dslforge.workspace/src/org/dslforge/workspace/internal/DatabaseService.java @@ -1,7 +1,7 @@ /** * * - * Copyright (c) 2015 PlugBee. All rights reserved. + * Copyright (c) 2016 PlugBee. All rights reserved. * * This program and the accompanying materials are made available * under the terms of the Eclipse Public License v1.0 which @@ -68,7 +68,7 @@ public EntityManagerFactory getEmf() { } return entityManagerFactory; } - + public EntityManagerFactory lookupEntityManagerFactory(String puName) { String filter = "(osgi.unit.name=" + puName + ")"; @SuppressWarnings("rawtypes") @@ -76,7 +76,7 @@ public EntityManagerFactory lookupEntityManagerFactory(String puName) { try { refs = context.getServiceReferences(EntityManagerFactory.class.getName(), filter); } catch (InvalidSyntaxException isEx) { - new RuntimeException("[ERROR] - Bad filter", isEx); + new RuntimeException("Found bad filter in manifest file.", isEx); } return (refs == null) ? null : (EntityManagerFactory) context.getService(refs[0]); } @@ -458,8 +458,7 @@ public User authenticateUser(String login, String password) { } public User changePwd(String userName, String pwd) { - EntityManagerFactory emf = getEmf(); - EntityManager em = emf.createEntityManager(); + EntityManager em = getEmf().createEntityManager(); Query q = em.createQuery("select u from User u where u.id = '" + userName + "'"); List users = q.getResultList(); if (users.size() > 1) diff --git a/plugins/org.dslforge.workspace/src/org/dslforge/workspace/internal/NavigatorImageProvider.java b/plugins/org.dslforge.workspace/src/org/dslforge/workspace/internal/WorkspaceImageProvider.java similarity index 90% rename from plugins/org.dslforge.workspace/src/org/dslforge/workspace/internal/NavigatorImageProvider.java rename to plugins/org.dslforge.workspace/src/org/dslforge/workspace/internal/WorkspaceImageProvider.java index 8a71379..faabee5 100644 --- a/plugins/org.dslforge.workspace/src/org/dslforge/workspace/internal/NavigatorImageProvider.java +++ b/plugins/org.dslforge.workspace/src/org/dslforge/workspace/internal/WorkspaceImageProvider.java @@ -1,7 +1,7 @@ /** * * - * Copyright (c) 2015 PlugBee. All rights reserved. + * Copyright (c) 2016 PlugBee. All rights reserved. * * This program and the accompanying materials are made available * under the terms of the Eclipse Public License v1.0 which @@ -15,7 +15,7 @@ */ package org.dslforge.workspace.internal; -public class NavigatorImageProvider { +public class WorkspaceImageProvider { public static final String FILE = "icons/file_obj.png"; public static final String MODEL = "icons/model.png"; diff --git a/plugins/org.dslforge.xtext.common/build.properties b/plugins/org.dslforge.xtext.common/build.properties index 3c0c97a..8abfe9e 100644 --- a/plugins/org.dslforge.xtext.common/build.properties +++ b/plugins/org.dslforge.xtext.common/build.properties @@ -7,4 +7,5 @@ bin.includes = META-INF/,\ icons/,\ lib/,\ src-js/,\ - about.html + about.html,\ + schema/