/* * (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.rm.view; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.Hashtable; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.openflexo.fge.DefaultDrawing; import org.openflexo.fge.DrawingGraphicalRepresentation; import org.openflexo.fge.GraphicalRepresentation; import org.openflexo.fge.ShapeGraphicalRepresentation; import org.openflexo.fge.geom.FGEPoint; import org.openflexo.foundation.DataModification; import org.openflexo.foundation.FlexoObservable; import org.openflexo.foundation.GraphicalFlexoObserver; import org.openflexo.foundation.rm.FlexoProject; import org.openflexo.foundation.rm.FlexoResource; import org.openflexo.foundation.rm.FlexoResourceData; import org.openflexo.foundation.rm.ResourceAdded; import org.openflexo.foundation.rm.ResourceRemoved; public class RMViewerRepresentation extends DefaultDrawing<FlexoProject> implements GraphicalFlexoObserver { private static final Logger logger = Logger.getLogger(RMViewerRepresentation.class.getPackage().getName()); private DrawingGraphicalRepresentation<FlexoProject> graphicalRepresentation; public RMViewerRepresentation(FlexoProject project) { super(project); graphicalRepresentation = new DrawingGraphicalRepresentation<FlexoProject>(this); project.addObserver(this); updateGraphicalObjectsHierarchy(); performAutomaticLayout(); } @Override public void delete() { getProject().deleteObserver(this); super.delete(); } @Override protected void buildGraphicalObjectsHierarchy() { for (FlexoResource<? extends FlexoResourceData> res : getProject()) { addDrawable(res, getProject()); } for (FlexoResource<? extends FlexoResourceData> r1 : getProject()) { for (FlexoResource<FlexoResourceData> r2 : r1.getDependentResources()) { if (r2.isRegistered()) { addDrawable(resourceDependancyBetween(r1, r2), getProject()); } else { if (logger.isLoggable(Level.WARNING)) { logger.warning("Found dependant resource not in project: " + r2 + " for resource " + r1); } } } for (FlexoResource<FlexoResourceData> r2 : r1.getSynchronizedResources()) { addDrawable(resourceSynchronizationBetween(r1, r2), getProject()); } } } public FlexoProject getProject() { return getModel(); } @Override public DrawingGraphicalRepresentation<FlexoProject> getDrawingGraphicalRepresentation() { return graphicalRepresentation; } @SuppressWarnings("unchecked") @Override public <O> GraphicalRepresentation<O> retrieveGraphicalRepresentation(O aDrawable) { return (GraphicalRepresentation<O>) buildGraphicalRepresentation(aDrawable); } private GraphicalRepresentation<?> buildGraphicalRepresentation(Object aDrawable) { if (aDrawable instanceof FlexoResource) { return new ResourceGR((FlexoResource) aDrawable, this); } else if (aDrawable instanceof ResourceDependancy) { return new ResourceDependancyGR((ResourceDependancy) aDrawable, this); } else if (aDrawable instanceof ResourceSynchronization) { return new ResourceSynchronizationGR((ResourceSynchronization) aDrawable, this); } logger.warning("Cannot build GraphicalRepresentation for " + aDrawable); return null; } @Override public void update(FlexoObservable observable, DataModification dataModification) { if (observable == getProject()) { // logger.info("Notified "+dataModification); if (dataModification instanceof ResourceAdded) { updateGraphicalObjectsHierarchy(); } else if (dataModification instanceof ResourceRemoved) { updateGraphicalObjectsHierarchy(); // removeDrawable(((RoleRemoved)dataModification).getRemovedRole(), getRoleList()); } } } private Map<FlexoResource, Map<FlexoResource, ResourceDependancy>> resourceDependancies; public ResourceDependancy resourceDependancyBetween(FlexoResource r1, FlexoResource r2) { if (resourceDependancies == null) { resourceDependancies = new Hashtable<FlexoResource, Map<FlexoResource, ResourceDependancy>>(); } Map<FlexoResource, ResourceDependancy> rl = resourceDependancies.get(r1); if (rl == null) { rl = new Hashtable<FlexoResource, ResourceDependancy>(); resourceDependancies.put(r1, rl); } ResourceDependancy returned = rl.get(r2); if (returned == null) { returned = new ResourceDependancy(r1, r2); rl.put(r2, returned); } return returned; } private Map<FlexoResource, Map<FlexoResource, ResourceSynchronization>> resourceSynchronizations; public ResourceSynchronization resourceSynchronizationBetween(FlexoResource r1, FlexoResource r2) { if (r1.getFullyQualifiedName().compareTo(r2.getFullyQualifiedName()) < 0) { return resourceSynchronizationBetween(r2, r1); } if (resourceSynchronizations == null) { resourceSynchronizations = new Hashtable<FlexoResource, Map<FlexoResource, ResourceSynchronization>>(); } Map<FlexoResource, ResourceSynchronization> rl = resourceSynchronizations.get(r1); if (rl == null) { rl = new Hashtable<FlexoResource, ResourceSynchronization>(); resourceSynchronizations.put(r1, rl); } ResourceSynchronization returned = rl.get(r2); if (returned == null) { returned = new ResourceSynchronization(r1, r2); rl.put(r2, returned); } return returned; } public static class ResourceDependancy { private FlexoResource r1; private FlexoResource r2; public ResourceDependancy(FlexoResource r1, FlexoResource r2) { super(); this.r1 = r1; this.r2 = r2; } public FlexoResource getR1() { return r1; } public FlexoResource getR2() { return r2; } public Date getLastSynchronizationDate() { return r1.getLastSynchronizedWithResource(r2); } } public static class ResourceSynchronization { private FlexoResource r1; private FlexoResource r2; public ResourceSynchronization(FlexoResource r1, FlexoResource r2) { super(); this.r1 = r1; this.r2 = r2; } public FlexoResource getR1() { return r1; } public FlexoResource getR2() { return r2; } } public void performAutomaticLayout() { double width = getDrawingGraphicalRepresentation().getWidth(); double height = getDrawingGraphicalRepresentation().getHeight(); int maxOrder = -1; Map<Integer, List<FlexoResource<? extends FlexoResourceData>>> resources = new HashMap<Integer, List<FlexoResource<? extends FlexoResourceData>>>(); for (FlexoResource<? extends FlexoResourceData> res : getProject()) { System.out.println("resource: " + res + " order " + res.getResourceOrder()); if (res.getResourceOrder() > maxOrder) { maxOrder = res.getResourceOrder(); } List<FlexoResource<? extends FlexoResourceData>> thisOrderResources = resources.get(res.getResourceOrder()); if (thisOrderResources == null) { thisOrderResources = new ArrayList<FlexoResource<? extends FlexoResourceData>>(); resources.put(res.getResourceOrder(), thisOrderResources); } thisOrderResources.add(res); } for (int i : resources.keySet()) { int j = 0; for (FlexoResource<? extends FlexoResourceData> r : resources.get(i)) { ShapeGraphicalRepresentation gr = (ShapeGraphicalRepresentation) getGraphicalRepresentation(r); gr.setLocation(new FGEPoint(i * width / maxOrder, j * height / resources.get(i).size())); j++; } } } }