/* * (c) Copyright 2010-2011 AgileBirds * * This file is part of OpenFlexo. * * OpenFlexo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenFlexo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>. * */ package org.openflexo.foundation.imported.action; import java.rmi.RemoteException; import java.util.Vector; import java.util.logging.Level; import java.util.logging.Logger; import org.openflexo.foundation.FlexoEditor; import org.openflexo.foundation.FlexoException; import org.openflexo.foundation.FlexoModelObject; import org.openflexo.foundation.FlexoRemoteException; import org.openflexo.foundation.action.FlexoActionType; import org.openflexo.foundation.gen.FlexoProcessImageBuilder; import org.openflexo.foundation.gen.FlexoProcessImageNotificationCenter; import org.openflexo.foundation.imported.DeltaStatus; import org.openflexo.foundation.imported.FlexoImportedProcessLibraryDelta; import org.openflexo.foundation.imported.FlexoImportedProcessLibraryDelta.DeltaVisitor; import org.openflexo.foundation.imported.FlexoImportedProcessLibraryDelta.ProcessDelta; import org.openflexo.foundation.rm.DuplicateResourceException; import org.openflexo.foundation.rm.FlexoProject; import org.openflexo.foundation.rm.InvalidFileNameException; import org.openflexo.foundation.wkf.FlexoImportedProcessLibrary; import org.openflexo.foundation.wkf.FlexoProcess; import org.openflexo.foundation.wkf.FlexoWorkflow; import org.openflexo.localization.FlexoLocalization; import org.openflexo.logging.FlexoLogger; import org.openflexo.ws.client.PPMWebService.PPMProcess; public class RefreshImportedProcessAction extends RefreshImportedObjectAction<RefreshImportedProcessAction, FlexoModelObject, FlexoModelObject> { protected static final Logger logger = FlexoLogger.getLogger(RefreshImportedProcessAction.class.getPackage().getName()); public static final FlexoActionType<RefreshImportedProcessAction, FlexoModelObject, FlexoModelObject> actionType = new FlexoActionType<RefreshImportedProcessAction, FlexoModelObject, FlexoModelObject>( "refresh_imported_processes") { @Override public boolean isEnabledForSelection(FlexoModelObject object, Vector<FlexoModelObject> globalSelection) { return object != null; } @Override public boolean isVisibleForSelection(FlexoModelObject object, Vector<FlexoModelObject> globalSelection) { return object != null && object.getProject().getWorkflow().getImportedProcessLibrary() != null; } @Override public RefreshImportedProcessAction makeNewAction(FlexoModelObject focusedObject, Vector<FlexoModelObject> globalSelection, FlexoEditor editor) { return new RefreshImportedProcessAction(focusedObject, globalSelection, editor); } }; static { FlexoModelObject.addActionForClass(actionType, FlexoWorkflow.class); FlexoModelObject.addActionForClass(actionType, FlexoProcess.class); FlexoModelObject.addActionForClass(actionType, FlexoImportedProcessLibrary.class); } protected RefreshImportedProcessAction(FlexoModelObject focusedObject, Vector<FlexoModelObject> globalSelection, FlexoEditor editor) { super(actionType, focusedObject, globalSelection, editor); } private FlexoImportedProcessLibraryDelta libraryDelta; private RefreshProcessDeltaVisitor visitor; @Override protected void doAction(Object context) throws FlexoException { FlexoProject project = getFocusedObject().getProject(); final FlexoWorkflow lib = project.getFlexoWorkflow(); Vector<FlexoProcess> processes = lib.getImportedProcesses(); String[] uris = new String[processes.size()]; int i = 0; for (FlexoProcess process : processes) { uris[i] = process.getURI(); i++; } PPMProcess[] updatedProcesses; try { updatedProcesses = getWebService().refreshProcesses(getLogin(), getMd5Password(), uris); } catch (RemoteException e) { if (logger.isLoggable(Level.WARNING)) { logger.log(Level.WARNING, "Remote exception: " + e.getMessage(), e); } throw new FlexoRemoteException(null, e); } if (updatedProcesses != null) { libraryDelta = new FlexoImportedProcessLibraryDelta(lib, updatedProcesses); visitor = new RefreshProcessDeltaVisitor(lib); libraryDelta.visit(visitor, true); FlexoProcessImageBuilder.startBackgroundDownloadOfSnapshots(visitor.getProcessToKeep(), getWebService(), getLogin(), getMd5Password()); for (FlexoProcess process : visitor.getProcessToDelete()) { if (visitor.getProcessToKeep().contains(process)) { if (logger.isLoggable(Level.WARNING)) { logger.warning("Visitor reported process " + process.getName() + " to be kept and deleted! Keeping it."); } continue; } if (process.isTopLevelProcess()) { process.markAsDeletedOnServer(); } else { if (visitor.getProcessToDelete().contains(process.getParentProcess())) { continue; } else { process.delete(); } } } } FlexoProcessImageNotificationCenter.getInstance().notifyNewImage(); } public FlexoImportedProcessLibraryDelta getLibraryDelta() { return libraryDelta; } public String getReport() { if (visitor != null) { return visitor.getReport(); } return FlexoLocalization.localizedForKey("refresh_has_not_been_performed"); } private final class RefreshProcessDeltaVisitor implements DeltaVisitor { private final FlexoWorkflow lib; private StringBuilder report; private Vector<FlexoProcess> processToDelete; private Vector<FlexoProcess> processToKeep; protected RefreshProcessDeltaVisitor(FlexoWorkflow lib) { this.lib = lib; this.processToDelete = new Vector<FlexoProcess>(); this.processToKeep = new Vector<FlexoProcess>(); report = new StringBuilder(); } @Override public void visit(ProcessDelta delta) { PPMProcess process = delta.getPPMProcess(); DeltaStatus status = delta.getStatus(); switch (status) { case UNCHANGED: break; case DELETED: if (delta.getFiProcess().isTopLevelProcess()) { if (!delta.getFiProcess().isDeletedOnServer()) { if (report.length() > 0) { report.append("\n"); } report.append(FlexoLocalization.localizedForKey("the_process")).append(" ").append(delta.getFiProcess().getName()) .append(" ").append(FlexoLocalization.localizedForKey("has_been_removed_from_server")); } } addToProcessToDelete(delta.getFiProcess()); break; case UPDATED: FlexoProcess fip = lib.getRecursivelyImportedProcessWithURI(process.getUri()); if (fip.isTopLevelProcess()) { if (report.length() > 0) { report.append("\n"); } report.append(FlexoLocalization.localizedForKey("the_process")).append(" ").append(fip.getName()).append(" ") .append(FlexoLocalization.localizedForKey("has_been_updated")); FlexoProcessImageBuilder.startBackgroundDownloadOfSnapshots(delta.getFiProcess(), getWebService(), getLogin(), getMd5Password()); } try { fip.updateFromObject(process); } catch (Exception e) { e.printStackTrace(); }// This does not take children into account (automatically handled with NEW/DELETED) break; case NEW: if (delta.getParent() == null) { // We have received a new root process-->we import it // Import process action will automatically verify that the process is not already somewhere in the workflow ImportProcessesAction importProcesses = ImportProcessesAction.actionType.makeNewEmbeddedAction(lib, null, RefreshImportedProcessAction.this); Vector<PPMProcess> v = new Vector<PPMProcess>(); v.add(delta.getPPMProcess()); importProcesses.setProcessesToImport(v); importProcesses.doAction(); if (importProcesses.getImportReport().getProperlyImported().size() == 1) { addToProcessToKeep(importProcesses.getImportReport().getProperlyImported().get(delta.getPPMProcess())); } } else { // We create the new sub-process try { addToProcessToKeep(FlexoProcess.createImportedProcessFromProcess(lib, delta.getPPMProcess())); } catch (InvalidFileNameException e) { if (logger.isLoggable(Level.SEVERE)) { logger.severe("Invalid file name thrown for process " + delta.getPPMProcess().getName() + ": " + e.getMessage()); } e.printStackTrace(); } catch (DuplicateResourceException e) { if (logger.isLoggable(Level.SEVERE)) { logger.severe("DuplicateResourceException file name thrown for process " + delta.getPPMProcess().getName() + ": " + e.getMessage()); } e.printStackTrace(); } } break; default: break; } } /** * @param newFIP */ private void addToProcessToKeep(FlexoProcess newFIP) { if (processToDelete.contains(newFIP)) { processToDelete.remove(newFIP); } processToKeep.add(newFIP); } /** * @param delta */ private void addToProcessToDelete(FlexoProcess process) { if (processToKeep.contains(process)) { return; } processToDelete.add(process); } public Vector<FlexoProcess> getProcessToKeep() { return processToKeep; } public Vector<FlexoProcess> getProcessToDelete() { return processToDelete; } public String getReport() { if (report.length() == 0) { return FlexoLocalization.localizedForKey("there_are_no_changes"); } return report.toString(); } } }