/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * 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: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.workbench.internal; import java.lang.reflect.InvocationTargetException; import java.net.InetSocketAddress; import java.util.HashSet; import java.util.Set; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.action.IAction; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IWorkbenchWindow; import org.simantics.application.arguments.ApplicationUtils; import org.simantics.application.arguments.IArguments; import org.simantics.application.arguments.SimanticsArguments; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.Session; import org.simantics.db.common.request.ReadRequest; import org.simantics.db.common.utils.NameUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.util.SimanticsKeys; import org.simantics.db.management.ISessionContext; import org.simantics.db.management.discovery.InetAddressUtils; import org.simantics.db.request.Read; import org.simantics.project.IProject; import org.simantics.project.ProjectKeys; import org.simantics.project.ProjectUtil; import org.simantics.project.exception.ProjectException; import org.simantics.project.utils.GraphPathUtils; import org.simantics.ui.db.SessionData; import org.simantics.ui.db.SessionRestoreUtils; import org.simantics.ui.internal.Activator; import org.simantics.ui.workbench.action.ChooseActionRequest; import org.simantics.utils.ui.ExceptionUtils; import org.simantics.utils.ui.action.IPriorityAction; import org.simantics.utils.ui.dialogs.ShowMessage; public class Initializer implements Runnable { private final IArguments args; // private String defaultPerspectiveId; /** * This will be !ok if something fatal for startup has happened. */ private final IStatus status = Status.OK_STATUS; private ISessionContext ctx; private IProject project; private Resource model; private final IWorkbenchWindow window; // private Resource experiment; public Initializer(IArguments args, IWorkbenchWindow window) { this.args = args; this.window = window; // this.defaultPerspectiveId = defaultPerspectiveId; } @Override public void run() { try { perform(); } catch (DatabaseException e) { e.printStackTrace(); } catch (ProjectException e) { e.printStackTrace(); } } public IStatus getStatus() { return status; } public ISessionContext getSessionContext() { return ctx; } public IProject getProject() { return project; } public Resource getModel() { return model; } public boolean perform() throws DatabaseException, ProjectException { // Nothing further can be done if no server is specified if (!args.contains(SimanticsArguments.SERVER)) return true; // Try to connect to designated server and project. // Use null local server location to indicate checkout String server = args.get(SimanticsArguments.SERVER); if(server.indexOf(':') == -1 && args.contains(SimanticsArguments.PORT)) { server = server+":"+args.get(SimanticsArguments.PORT); } InetSocketAddress serverAddress = InetAddressUtils.parseUnresolved(server); String[] projectPath = ApplicationUtils.decodePath(args.get(SimanticsArguments.PROJECT)); final SessionData data = new SessionData(null, serverAddress, projectPath); final MultiStatus status = new MultiStatus(Activator.PLUGIN_ID, IStatus.OK, "Database session could not be initialized.", null); // final ProgressMonitorDialog dialog = new ProgressMonitorDialog(null); final ProgressMonitorDialog dialog = new ProgressMonitorDialog(null); try { dialog.run(false, true, new IRunnableWithProgress() { @Override public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { ctx = SessionRestoreUtils.restoreSession(status, monitor, data); //ctx = sessionResult; } }); } catch (InvocationTargetException e) { ExceptionUtils.logAndShowError(e); } catch (InterruptedException e) { ExceptionUtils.logAndShowError(e); } //IDiscoveryModel model = // IDiscoveryData[] iData = ProjectPlugin.getWorkspace().getDiscoveryModel().getDataSources(); // for(int i = 0; i < iData.length; i++) { // IDiscoveryData d = iData[i]; // if(d.getLabel().equals(IWorkspaceConstants.DIRECT_SERVERS_LABEL)) { // ServerInfo serverInfo = new ServerInfo(d.getLabel(), serverAddress); // ServerData serverData = new ServerData(null, serverInfo, null); // IServerData[] iServerData = d.getServers(); // // IServerData[] newServerData = new IServerData[iServerData.length+1]; // // int y; // for(y = 0; y < iServerData.length; y++) { // newServerData[y] = iServerData[y]; // } // // newServerData[y] = serverData; // // d.setServers(newServerData); // ProjectPlugin.getWorkspace().getDiscoveryModel().updateDataSource(d); // break; // } // // } //status = sessionResult.status; //if (!status.isOK()) { // return false; //} if (ctx == null) { // Its okay to start the workbench, it will just be reset as the // connection failed. return true; } // FIXME: COMPLETE HACK for simupedia // Add a discovery service to get in touch /* IDiscoveryModel discoveryModel = ProjectPlugin.getWorkspace().getDiscoveryModel(); File discoveryFile = ProjectPlugin.getDefault().getStateLocation().append("simupedia-discovery.txt").toFile(); FileWriter fw = null; try { // Overwrite the file. fw = new FileWriter(discoveryFile, false); String serverLine = String.format("'%s' %s\n", data.getAddress().getHostName(), server); fw.write(serverLine); } catch (IOException e) { e.printStackTrace(); } finally { FileUtils.uncheckedClose(fw); } try { // Add a non-persistent simupedia discovery DiscoveryData d = new DiscoveryData(IDiscoveryType.REMOTE, "Simupedia", discoveryFile); discoveryModel.addDataSource(d); } catch (MalformedURLException e) { // Should never happen. throw new Error(e); } */ // Initialize project if (args.contains(SimanticsArguments.NEW_PROJECT)) { throw new UnsupportedOperationException(); //project = newProject(ctx); } else if (args.contains(SimanticsArguments.PROJECT)) { project = loadProject(ctx, projectPath); } // Only proceed with model and experiment loading if a project was // successfully created or loaded. if (project != null) { ctx.setHint(ProjectKeys.KEY_PROJECT, project); ctx.setHint(SimanticsKeys.KEY_PROJECT, project.get()); // Load model if (args.contains(SimanticsArguments.NEW_MODEL)) { //model = newModel(ctx.getSession(), project); } else if (args.contains(SimanticsArguments.MODEL)) { String[] modelPath = ApplicationUtils.decodePath(args.get(SimanticsArguments.MODEL)); model = findModel(ctx.getSession(), project, modelPath); } // if (model != null) { // findDiagram(ctx.getSession(), model, project); // } // TODO: load experiment if (args.contains(SimanticsArguments.EXPERIMENT)) { // String[] experimentPath = decodePath(args.get(ProConfArguments.EXPERIMENT)); } } return true; } IProject loadProject(ISessionContext ctx, final String[] projectNamePath) throws DatabaseException, ProjectException { IProject project = ctx.getSession().syncRequest(new Read() { @Override public IProject perform(ReadGraph graph) throws DatabaseException { Resource projects = graph.getResource("http://Projects"); Resource[] path = GraphPathUtils.toResourcePath(graph, projects, projectNamePath, graph .getBuiltins().ConsistsOf); if (path.length == 0) { IllegalArgumentException e = new IllegalArgumentException(""); ShowMessage.showError("Error loading the existing project", e.getMessage()); throw new DatabaseException(e); } return ProjectUtil.loadProject(graph, path[path.length - 1]); } }); project.activate(); return project; // final GraphRequestWithResult request = new GraphRequestWithResult() { // @Override // public IProject performWithResult(Graph g) throws Exception { // } // }; // ctx.getSession().syncRead(request); // if (request.getException() != null) { // ShowMessage.showError("Error loading the existing project", request.getException().getMessage()); // return null; // } // return request.getResult(); } Resource findModel(final Session session, final IProject project, final String[] modelPath) throws DatabaseException { return session.syncRequest(new Read() { @Override public Resource perform(ReadGraph graph) throws DatabaseException { Resource[] path = GraphPathUtils.toResourcePath(graph, project.get(), modelPath, graph .getBuiltins().ConsistsOf); if (path.length == 0) { IllegalArgumentException e = new IllegalArgumentException(""); ShowMessage.showError("Error loading the existing project", e.getMessage()); throw new DatabaseException(e); } else return path[path.length - 1]; } }); // final GraphRequestWithResult request = new GraphRequestWithResult() { // @Override // public Resource performWithResult(Graph g) { // Resource[] path = GraphPathUtils.toResourcePath(g, project.getResource(), modelPath, // g.getBuiltins().ConsistsOf); // if (path.length == 0) // throw new IllegalArgumentException(""); // return path[path.length - 1]; // } // }; // session.syncRead(request); // if (request.getException() != null) { // ShowMessage.showError("Error loading the existing project", request.getException().getMessage()); // return null; // } // return request.getResult(); } final Set reservedProjectNames = new HashSet(); // IProject newProject(final ISessionContext ctx) throws DatabaseException { // // --------------------------------------------------------------------- // // Show the wizard to the user. // final NewProjectModel2 model = ProjectWizardUtil.initializeNewProjectModel2(new NullProgressMonitor(), ctx); // final NewProjectWizard2 wizard = new NewProjectWizard2(ctx.getSession(), model, null); // int ok = new WizardDialog(null, wizard).open(); // if (ok != Window.OK) { // // User cancelled the wizard. // return null; // } // // final DataContainer project = new DataContainer(); // // ctx.getSession().syncRequest(new WriteRequest() { // // @Override // public void perform(WriteGraph g) { // // try { // // // TODO: add features // System.out.println("TODO: add features to project"); // Collection fds = Collections.emptyList(); // Resource res = ProjectUtil.createProject(g, model.projectName, fds); // project.set(ProjectUtil.loadProject(g, res, false)); // // } catch (Exception e) { // ShowMessage.showError("Error creating new project", e.getMessage()); // } // // } // // }); // // return project.get(); // // } /* Resource newModel(final Session session, final IProject project) { final ISimulationProjectParticipant sim = project.getSingleParticipant(ISimulationProjectParticipant.class); if (sim == null) return null; final Resource[] result = { null }; final Semaphore sem = new Semaphore(0); findModelLibrary(session, project.getResource(), new RunnableWithParameter() { @Override public void run(Resource modelLibrary) { sim.createModel(modelLibrary, new RunnableWithParameter() { @Override public void run(Resource model) { result[0] = model; sem.release(); } }, new RunnableWithParameter() { @Override public void run(Throwable e) { ErrorLogger.defaultLogError("New model creation failed, see exception for details.", e); sem.release(); } }); } }, new RunnableWithParameter() { @Override public void run(Throwable e) { if (e != null) ErrorLogger.defaultLogError("New model creation failed, see exception for details.", e); else ErrorLogger.defaultLogError("New model creation failed, no model library found.", null); sem.release(); } }); // Wait until the model creation has finished or failed. try { sem.acquire(); } catch (InterruptedException e) { } return result[0]; } */ /* void findModelLibrary(Session session, final Resource project, final RunnableWithParameter libraryAction, final RunnableWithParameter errorCallback) { // TODO: all of this is not that generic, what is someone decices he/she // doesn't want a model library called Models at the root of his/her // project ?? // If the new model consists of a single diagram, open it. session.asyncRequest(new WriteRequest() { @Override public void perform(WriteGraph g) throws Exception { Resource modelLibrary = null; try { Builtins b = g.getBuiltins(); for (Resource r : g.getObjects2(project, b.ConsistsOf)) { if (g.isInstanceOf2(r, b.ModelLibrary)) { modelLibrary = r; break; } } // FIXME: this is definitely project specific, not generic. if (modelLibrary == null) { modelLibrary = InstanceFactory.instantiate(g, b.ModelLibrary); GraphUtils.addRelatedScalarString(g, modelLibrary, b.HasName, "Models"); g.claim(project, b.ConsistsOf, modelLibrary); } libraryAction.run(modelLibrary); } catch (Exception e) { errorCallback.run(e); } } }); } */ // void findDiagram(Session session, final Resource model, final IProject project) { // // If the new model consists of a single diagram, open it. // session.asyncRequest(new ReadRequest() { // @Override // public void run(ReadGraph g) throws DatabaseException { // Builtins b = g.getBuiltins(); // DiagramResource dr = DiagramResource.getInstance(g); // for (Resource r : g.getObjects(model, b.ConsistsOf)) { // if (g.isInstanceOf(r, dr.Diagram)) { // String defaultPerspective = project.getHint(ProjectKeys.DEFAULT_PERSPECTIVE); // openPreferredEditor(ctx.getSession(), r, defaultPerspective); // break; // } // } // } // }); // } void openPreferredEditor(Session s, final Resource r, final String defaultPerspective) { s.asyncRequest(new ReadRequest() { @Override public void run(ReadGraph g) throws DatabaseException { final String resourceName = NameUtils.getSafeName(g, r); final IPriorityAction[] actions = ChooseActionRequest.findActions(g, r, defaultPerspective); if (actions == null) return; Display.getDefault().asyncExec(new Runnable() { @Override public void run() { IAction action = ChooseActionRequest.chooseAction(null, actions, resourceName); if (action == null) return; action.run(); } }); } }); } }