Java tutorial
package nubisave.component.graph.splitteradaption; /* * Copyright (c) 2003, the JUNG Project and the Regents of the University of * California All rights reserved. * * This software is open-source under the BSD license; see either "license.txt" * or http://jung.sourceforge.net/license.txt for a description. * */ import com.github.joe42.splitter.util.file.PropertiesUtil; import nubisave.component.graph.mouseplugins.extension.AbstractNubisaveComponentEdgeCreator; import nubisave.component.graph.mouseplugins.extension.PreventEdgeCreationForRestrictedPorts; import nubisave.component.graph.mouseplugins.extension.ToggleActivateNubisaveComponentOnDoubleClick; import nubisave.component.graph.mouseplugins.StorageServicePicker; import nubisave.component.graph.mouseplugins.PopupEditor; import nubisave.component.graph.vertice.NubiSaveComponent; import nubisave.component.graph.vertice.GenericNubiSaveComponent; import nubisave.component.graph.mouseplugins.extension.DataVertexEdgeCreator; import nubisave.component.graph.mouseplugins.extension.AbstractNubiSaveComponentCreator; import nubisave.component.graph.edge.WeightedNubisaveVertexEdge; import nubisave.component.graph.edge.NubiSaveEdge; import edu.uci.ics.jung.algorithms.filters.VertexPredicateFilter; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.IOException; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JApplet; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.JPanel; import org.apache.commons.collections15.Factory; import nubisave.component.graph.tranformer.BufferedImageDelegatorVertexIconTransformer; import nubisave.component.graph.tranformer.BufferedImageDelegatorVertexShapeTransformer; import nubisave.component.graph.vertice.AbstractNubisaveComponent; import edu.uci.ics.jung.algorithms.layout.AbstractLayout; import edu.uci.ics.jung.algorithms.layout.StaticLayout; import edu.uci.ics.jung.graph.Graph; import edu.uci.ics.jung.graph.util.EdgeType; import edu.uci.ics.jung.visualization.GraphZoomScrollPane; import edu.uci.ics.jung.visualization.RenderContext; import edu.uci.ics.jung.visualization.VisualizationViewer; import edu.uci.ics.jung.visualization.control.PluggableGraphMouse; import edu.uci.ics.jung.visualization.control.ScalingGraphMousePlugin; import edu.uci.ics.jung.visualization.control.TranslatingGraphMousePlugin; import edu.uci.ics.jung.visualization.control.ViewScalingControl; import edu.uci.ics.jung.visualization.decorators.EdgeShape; import edu.uci.ics.jung.visualization.decorators.ToStringLabeller; import edu.uci.ics.jung.visualization.picking.PickedState; import edu.uci.ics.jung.visualization.renderers.Renderer; import java.awt.BasicStroke; import java.awt.Dialog; import java.awt.Dialog.ModalityType; import java.awt.Point; import java.awt.Stroke; import java.awt.Window; import java.awt.event.InputEvent; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.util.ArrayList; import java.util.HashMap; import javax.swing.JDialog; import javax.swing.SwingUtilities; import javax.swing.WindowConstants; import net.contentobjects.jnotify.*; import nubisave.Nubisave; import nubisave.Services; import nubisave.StorageService; import nubisave.MatchmakerService; import nubisave.component.graph.mouseplugins.ExtensibleNubisaveComponentMousePlugin; import nubisave.component.graph.mouseplugins.VertexPicker; import nubisave.component.graph.pickedvertexlistener.BufferedImageDelegatorHighlighter; import nubisave.component.graph.SortedSparseMultiGraph; import nubisave.component.graph.tranformer.GenericComponentLabeller; import nubisave.component.graph.edge.DataVertexEdge; import nubisave.component.graph.splitteradaption.ActionKeyAdapter; import nubisave.component.graph.splitteradaption.ActionKeyAdapter; import nubisave.component.graph.vertice.interfaces.NubiSaveVertex; import nubisave.component.graph.vertice.interfaces.VertexGroup; import nubisave.ui.AddServiceDialog; import nubisave.ui.CustomServiceDlg; import org.apache.commons.collections15.Predicate; import org.apache.commons.collections15.Transformer; import org.ini4j.Ini; /** * */ public class NubisaveEditor extends JApplet { private static final long serialVersionUID = -2023243689258876721L; private String storage_directory; Graph<NubiSaveVertex, NubiSaveEdge> graph; NubiSaveComponent nubiSaveComponent; AbstractLayout<NubiSaveVertex, NubiSaveEdge> layout; /** * the visual component and renderer for the graph */ VisualizationViewer<NubiSaveVertex, NubiSaveEdge> vv; String instructions = "<html>" + "<h3>Create a Component:</h3>" + "<ul>" + "<li>Click the <b>Local Component</b> button to select a deployment descriptor in the opening dialog" + "<li>Click on an empty area of the editor for the component to be added" + "</ul>" + "<h3>Transform the Display:</h3>" + "<ul>" + "<li>Press the mouse on an empty area to drag it and then release the mouse to change the viewpoint" + "<li>Turn the mouse wheel inside the editor to zoom in and out" + "</ul>" + "<h3>Move a Component:</h3>" + "<ul>" + "<li>Press the mouse on a component to drag it and then release the mouse to move it to a new location" + "</ul>" + "<h3>Delete a Component:</h3>" + "<ul>" + "<li>Right-click on the component to open a popup dialog and select <b>Delete Component</b>" + "<li>This action will open a dialog asking if the component should be deleted" + "<li>A shortcut is to select a component by clicking onto it. This will highlight the component" + "<li>Then press the <b>Del</b> key on your keyboard, which deletes the selected component instantly" + "</ul>" + "<h3>Configure a Component:</h3>" + "<ul>" + "<li>Right-click on the component to open a popup dialog and select <b>Configure Component</b>" + "<li>Set the desired parameters in the opening dialog and click <b>Apply</b> to confirm the configuration or abort it by clicking the <b>Cancel</b> button" + "<li>To increase the <b>weight</b> of a connection between components, connect the ports of these components again" + "<li>The weight is displayed as a label of the connecting arrows. It determines the fraction of data being stored at the component offering the <b>Provided Port</b>" + "</ul>" + "<h3>Configure the Component Architecture:</h3>" + "<ul>" + "<li>Press the mouse on the <b>Provided Port<b> or the <b>Required Port</b> of a component" + "<li>Drag the mouse to the corresponding port of an other component and release the mouse" + "<li>This will connect the ports by an arrow" + "<li>The connection means that data of the component instance with the <b>Required Port</b> is stored at the component instance offering the provided port" + "<li>A port might support a restricted number of connections. Once this number is satisfied, no more connections can be made to this port" + "</ul>" + "<h3>Instantiate a Component:</h3>" + "<ul>" + "<li>Double-click a component to mount it and wait until a green checkmark appears" + "<li>At first, the <b>NubiSave<b> component should be instantiated if it is not already" + "<li>To remove an instance, double-click the component again and wait until the checkmark disappears or remove the component" + "</ul>" + "<h3>Transfer Data:</h3>" + "<ul>" + "<li>Press the mouse on the <b>Data Icon</b> of a component and drag it to an other <b>Data Icon</b>" + "<li>Releasing the mouse will display a transfer connection between the <b>Data Icons</b>" + "<li>All data stored at the component instance with the <b>Data Icon</b> first selected will be transfered to the second component instance" + "<li>The transfer progress is displayed in the label of the connection, which disappears after the transfer is completed" + "<li>Note that the transfer can only be done between two instantiated components" + "</ul>" + "</html>"; private final DataVertexEdgeFactory dataVertexEdgeFactory; /** * create an instance of a simple graph with popup controls to * create a graph. * */ public NubisaveEditor() { // create a simple graph for the demo graph = new SortedSparseMultiGraph<NubiSaveVertex, NubiSaveEdge>(); this.layout = new StaticLayout<NubiSaveVertex, NubiSaveEdge>(graph, new Dimension(600, 600)); vv = new VisualizationViewer<NubiSaveVertex, NubiSaveEdge>(layout); dataVertexEdgeFactory = new DataVertexEdgeFactory(); storage_directory = new PropertiesUtil("nubi.properties").getProperty("storage_configuration_directory"); //Immediate Adaption to external changes int mask = JNotify.FILE_CREATED | JNotify.FILE_DELETED | JNotify.FILE_MODIFIED | JNotify.FILE_RENAMED; boolean watchSubtree = false; // try { // JNotify.addWatch(Nubisave.mainSplitter.getConfigDir(), mask, watchSubtree, new JNotifyConfigUpdater(dataVertexEdgeFactory, graph, vv)); // } catch (Exception ex) { // Logger.getLogger(NubisaveEditor.class.getName()).log(Level.SEVERE, null, ex); // } vv.setBackground(Color.white); vv.getRenderContext().setEdgeStrokeTransformer(new EdgeWeightStrokeFunction<NubiSaveEdge>()); vv.getRenderContext().setEdgeLabelTransformer(new ToStringLabeller<NubiSaveEdge>()); vv.getRenderContext() .setVertexShapeTransformer(new BufferedImageDelegatorVertexShapeTransformer<NubiSaveVertex>()); vv.getRenderContext() .setVertexIconTransformer(new BufferedImageDelegatorVertexIconTransformer<NubiSaveVertex>()); vv.setVertexToolTipTransformer(vv.getRenderContext().getVertexLabelTransformer()); vv.getRenderer().getVertexLabelRenderer().setPosition(Renderer.VertexLabel.Position.CNTR); vv.getRenderContext().setVertexLabelTransformer(new GenericComponentLabeller<NubiSaveVertex>()); vv.getRenderContext().setEdgeShapeTransformer(new EdgeShape.Line<NubiSaveVertex, NubiSaveEdge>()); new BufferedImageDelegatorHighlighter(vv.getPickedVertexState()); Container content = this; final GraphZoomScrollPane panel = new GraphZoomScrollPane(vv); content.add(panel); final StatefulNubiSaveComponentFactory vertexFactory = new StatefulNubiSaveComponentFactory(); Factory<? extends NubiSaveEdge> edgeFactory = new WeightedNubisaveVertexEdgeFactory(); final PluggableGraphMouse graphMouse = createPluggableGraphMouse(vv.getRenderContext(), vertexFactory, edgeFactory, dataVertexEdgeFactory); // try { // // the EditingGraphMouse will pass mouse event coordinates to the // // vertexLocations function to set the locations of the vertices as // // they are created //graphMouse.setVertexLocations(vertexLocations); // nubiSaveComponent = new NubiSaveComponent(); // nubiSaveComponent.addToGraph(vv, new java.awt.Point((int)layout.getSize().getHeight()/2,(int)layout.getSize().getWidth()/2)); // } catch (IOException ex) { // Logger.getLogger(NubisaveEditor.class.getName()).log(Level.SEVERE, null, ex); // } vv.setGraphMouse(graphMouse); vv.addKeyListener(new ActionKeyAdapter(vv.getPickedVertexState(), graph)); JButton help = new JButton("Help"); help.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { JOptionPane.showMessageDialog(vv, instructions); } }); addServicesToGraph(); Graph<AbstractNubisaveComponent, Object> nubisaveComponentGraph = new VertexPredicateFilter( new Predicate() { @Override public boolean evaluate(Object vertex) { return vertex instanceof AbstractNubisaveComponent; } }).transform(graph); interconnectNubisaveComponents(nubisaveComponentGraph, edgeFactory); //interconnectNubisaveComponents(); JPanel controls = new JPanel(); JButton chooseLocalComponent = new JButton("Custom Storage/Modification/Splitter Module"); chooseLocalComponent.addActionListener(new ActionListener() { /** * Create new {@link StorageService} from chosen file and set it as the next Vertex to create in {@link StatefulNubiSaveComponentFactory} */ @Override public void actionPerformed(ActionEvent ae) { CustomServiceDlg cusDlg = new CustomServiceDlg(); cusDlg.pack(); cusDlg.setLocationRelativeTo(null); cusDlg.setTitle("Module Selection"); cusDlg.setModalityType(Dialog.ModalityType.APPLICATION_MODAL); cusDlg.setVisible(true); String module = (String) cusDlg.getItemName(); if (module != null) { module = module.split("\\.")[0]; } if (module != null) { if (cusDlg.okstatus == "True") { if (module.toLowerCase().equals("nubisave")) { StorageService newService = new StorageService(module); try { vertexFactory.setNextInstance(new NubiSaveComponent(newService)); //nubiSaveComponent.addToGraph(vv, new java.awt.Point((int)layout.getSize().getHeight()/2,(int)layout.getSize().getWidth()/2)); } catch (IOException ex) { Logger.getLogger(NubisaveEditor.class.getName()).log(Level.SEVERE, null, ex); } nubisave.Nubisave.services.addNubisave(newService); } else { StorageService newService = new StorageService(module); try { vertexFactory.setNextInstance(new GenericNubiSaveComponent(newService)); } catch (IOException ex) { Logger.getLogger(NubisaveEditor.class.getName()).log(Level.SEVERE, null, ex); } nubisave.Nubisave.services.add(newService); } } } else { JFileChooser customStorageserviceChooser = new javax.swing.JFileChooser(); customStorageserviceChooser.setCurrentDirectory( new java.io.File(nubisave.Nubisave.mainSplitter.getMountScriptDir())); customStorageserviceChooser.setDialogTitle("Custom Service"); customStorageserviceChooser.setFileFilter(new IniFileFilter()); int returnVal = customStorageserviceChooser.showOpenDialog(null); if (returnVal == JFileChooser.APPROVE_OPTION) { File file = customStorageserviceChooser.getSelectedFile(); if (file.getName().toLowerCase().equals("nubisave.ini")) { StorageService newService = new StorageService(file); try { vertexFactory.setNextInstance(new NubiSaveComponent(newService)); //nubiSaveComponent.addToGraph(vv, new java.awt.Point((int)layout.getSize().getHeight()/2,(int)layout.getSize().getWidth()/2)); } catch (IOException ex) { Logger.getLogger(NubisaveEditor.class.getName()).log(Level.SEVERE, null, ex); } nubisave.Nubisave.services.addNubisave(newService); } else { StorageService newService = new StorageService(file); try { vertexFactory.setNextInstance(new GenericNubiSaveComponent(newService)); } catch (IOException ex) { Logger.getLogger(NubisaveEditor.class.getName()).log(Level.SEVERE, null, ex); } nubisave.Nubisave.services.add(newService); } } } } }); controls.add(chooseLocalComponent); JButton searchServiceComponent = new JButton("Storage Service Directory"); searchServiceComponent.addActionListener(new ActionListener() { /** * Create new {@link StorageService} from chosen file and set it as the next Vertex to create in {@link StatefulNubiSaveComponentFactory} */ @Override public void actionPerformed(ActionEvent ae) { AddServiceDialog addServiceDlg = new AddServiceDialog(null, true); addServiceDlg.setVisible(true); for (MatchmakerService newService : addServiceDlg.getSelectedServices()) { try { vertexFactory.setNextInstance(new GenericNubiSaveComponent(newService)); } catch (IOException ex) { Logger.getLogger(AddServiceDialog.class.getName()).log(Level.SEVERE, null, ex); } } } }); controls.add(searchServiceComponent); controls.add(help); content.add(controls, BorderLayout.SOUTH); } /** * Add {@link Nubisave#services} to graph if they are not yet displayed there. */ private void addServicesToGraph() { for (int i = 0; i < nubisave.Nubisave.services.size(); i++) { StorageService persistedService = nubisave.Nubisave.services.get(i); AbstractNubisaveComponent vertex = null; if (persistedService.getName().toLowerCase().equals("nubisave")) { try { vertex = new NubiSaveComponent(persistedService); } catch (IOException ex) { Logger.getLogger(NubisaveEditor.class.getName()).log(Level.SEVERE, null, ex); } } else { try { vertex = new GenericNubiSaveComponent(persistedService); } catch (IOException ex) { Logger.getLogger(NubisaveEditor.class.getName()).log(Level.SEVERE, null, ex); } } Point pos = persistedService.getGraphLocation(); if (pos == null) { pos = new Point(new java.awt.Point((int) layout.getSize().getHeight() / 2, (int) layout.getSize().getWidth() / 2 - i * 10 - 10)); } if (!graph.containsVertex(vertex)) { System.out.println("add vertice " + vertex.getUniqueName()); vertex.addToGraph(vv, pos); layout.setLocation(vertex, vv.getRenderContext().getMultiLayerTransformer().inverseTransform(pos)); } } } class StatefulNubiSaveComponentFactory implements Factory<AbstractNubisaveComponent> { private AbstractNubisaveComponent next; /** * @return the last instance of AbstractNubiSaveComponent passed in by {@link #setNextInstance()} or null */ @Override public AbstractNubisaveComponent create() { AbstractNubisaveComponent ret = next; next = null; return ret; } /** * Set the next value to return by this factory. * @param next */ public void setNextInstance(AbstractNubisaveComponent next) { this.next = next; } } public class WeightedNubisaveVertexEdgeFactory implements Factory<WeightedNubisaveVertexEdge> { public WeightedNubisaveVertexEdge create() { return new WeightedNubisaveVertexEdge(); } } class DataVertexEdgeFactory implements Factory<DataVertexEdge> { public DataVertexEdge create() { return new DataVertexEdge(); } } /** * Allow only directories, or files with ".ini" extension */ class IniFileFilter extends javax.swing.filechooser.FileFilter { @Override public boolean accept(File file) { return file.isDirectory() || file.getAbsolutePath().endsWith(".ini"); } @Override public String getDescription() { return "*.ini"; } } private final static class EdgeWeightStrokeFunction<NubisaveEdge> implements Transformer<NubisaveEdge, Stroke> { public Stroke transform(NubisaveEdge e) { int weight = 1; if (e instanceof WeightedNubisaveVertexEdge) weight = ((WeightedNubisaveVertexEdge) e).getWeight(); return new BasicStroke(1 + weight); } } protected PluggableGraphMouse createPluggableGraphMouse(RenderContext<NubiSaveVertex, NubiSaveEdge> rc, Factory<AbstractNubisaveComponent> vertexFactory, Factory<? extends NubiSaveEdge> edgeFactory, DataVertexEdgeFactory dataVertexEdgeFactory) { PluggableGraphMouse graphMouse = new PluggableGraphMouse(); VertexPicker<NubiSaveVertex, NubiSaveEdge> pickingPlugin = new VertexPicker<NubiSaveVertex, NubiSaveEdge>(); TranslatingGraphMousePlugin translatingPlugin = new TranslatingGraphMousePlugin(InputEvent.BUTTON1_MASK); ScalingGraphMousePlugin scalingPlugin = new ScalingGraphMousePlugin(new ViewScalingControl(), 0, 1.1f, 1 / 1.1f); PopupEditor popupEditingPlugin = new PopupEditor(edgeFactory); StorageServicePicker<NubiSaveVertex, NubiSaveEdge> storageServicePickingPlugin = new StorageServicePicker<NubiSaveVertex, NubiSaveEdge>(); ExtensibleNubisaveComponentMousePlugin extendablePlugin = new ExtensibleNubisaveComponentMousePlugin( vertexFactory, edgeFactory); extendablePlugin.addEventListener(new AbstractNubiSaveComponentCreator(vv, graph, vertexFactory)); extendablePlugin.addEventListener(new ToggleActivateNubisaveComponentOnDoubleClick(vv, graph)); extendablePlugin.addEventListener(new PreventEdgeCreationForRestrictedPorts(vv, graph)); extendablePlugin.addEventListener(new DataVertexEdgeCreator(vv, graph, dataVertexEdgeFactory)); extendablePlugin.addEventListener(new AbstractNubisaveComponentEdgeCreator(vv, graph, (WeightedNubisaveVertexEdgeFactory) edgeFactory)); graphMouse.add(scalingPlugin); graphMouse.add(extendablePlugin); graphMouse.add(storageServicePickingPlugin); graphMouse.add(translatingPlugin); graphMouse.add(popupEditingPlugin); return graphMouse; } protected void interconnectNubisaveComponents(Graph<AbstractNubisaveComponent, Object> nubisaveComponentGraph, Factory<? extends NubiSaveEdge> edgeFactory) { boolean connected = false; WeightedNubisaveVertexEdge edge; File file = new File(storage_directory + "/" + "connections.txt"); HashMap hh = new HashMap(); ArrayList<AbstractNubisaveComponent> myNodeList = new ArrayList<AbstractNubisaveComponent>( nubisaveComponentGraph.getVertices()); ArrayList str = new ArrayList(); for (int i = 0; i < nubisaveComponentGraph.getVertices().size(); i++) { str.add(myNodeList.get(i).getUniqueName()); } if (file.exists()) { BufferedReader reader = null; try { reader = new BufferedReader(new FileReader(file)); String strLine; try { //Read the text file Line By Line while ((strLine = reader.readLine()) != null) { String startVertex = strLine.split(" ")[0]; String endVertex = strLine.split(" ")[1]; hh.put(startVertex, endVertex); for (AbstractNubisaveComponent component : nubisaveComponentGraph.getVertices()) { if (component.getUniqueName().equals(startVertex)) { String endpoint = (String) hh.get(startVertex); int pos = str.indexOf(endpoint); AbstractNubisaveComponent endcomponent = myNodeList.get(pos); edge = (WeightedNubisaveVertexEdge) edgeFactory.create(); edge.setWeight(component.getNrOfFilePartsToStore()); graph.addEdge(edge, component.getRequiredPorts().iterator().next(), endcomponent.getProvidedPorts().iterator().next(), EdgeType.DIRECTED); } } } reader.close(); } catch (IOException ex) { Logger.getLogger(NubisaveEditor.class.getName()).log(Level.SEVERE, null, ex); } } catch (FileNotFoundException ex) { Logger.getLogger(NubisaveEditor.class.getName()).log(Level.SEVERE, null, ex); } } } }