You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@taverna.apache.org by st...@apache.org on 2018/06/29 10:55:13 UTC
[26/27] incubator-taverna-plugin-component git commit: package rename
folders
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/annotation/SemanticAnnotationPanel.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/annotation/SemanticAnnotationPanel.java b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/annotation/SemanticAnnotationPanel.java
new file mode 100644
index 0000000..536a87d
--- /dev/null
+++ b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/annotation/SemanticAnnotationPanel.java
@@ -0,0 +1,271 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package io.github.taverna_extras.component.ui.annotation;
+
+import static java.awt.BorderLayout.CENTER;
+import static java.awt.BorderLayout.NORTH;
+import static java.awt.Color.WHITE;
+import static java.awt.Font.BOLD;
+import static java.awt.GridBagConstraints.BOTH;
+import static java.awt.GridBagConstraints.EAST;
+import static java.awt.GridBagConstraints.HORIZONTAL;
+import static java.awt.GridBagConstraints.NONE;
+import static java.awt.GridBagConstraints.SOUTHEAST;
+import static java.lang.Integer.MIN_VALUE;
+import static java.lang.String.format;
+import static javax.swing.JOptionPane.ERROR_MESSAGE;
+import static javax.swing.JOptionPane.OK_CANCEL_OPTION;
+import static javax.swing.JOptionPane.OK_OPTION;
+import static javax.swing.JOptionPane.showConfirmDialog;
+import static javax.swing.JOptionPane.showMessageDialog;
+import static io.github.taverna_extras.component.ui.annotation.SemanticAnnotationUtils.getDisplayName;
+import static io.github.taverna_extras.component.ui.annotation.SemanticAnnotationUtils.getObjectName;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.List;
+import java.util.Set;
+
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.border.EmptyBorder;
+
+import io.github.taverna_extras.component.api.profile.SemanticAnnotationProfile;
+
+import org.apache.jena.ontology.OntProperty;
+import org.apache.jena.rdf.model.RDFNode;
+import org.apache.jena.rdf.model.Statement;
+import org.apache.taverna.lang.ui.DeselectingButton;
+
+public class SemanticAnnotationPanel extends JPanel {
+ private static final long serialVersionUID = -5949183295606132775L;
+
+ private List<PropertyPanelFactorySPI> propertyPanelFactories; //FIXME beaninject
+ private final AbstractSemanticAnnotationContextualView semanticAnnotationContextualView;
+ private final SemanticAnnotationProfile semanticAnnotationProfile;
+ private final Set<Statement> statements;
+ private final boolean allowChange;
+ private final PropertyPanelFactorySPI bestFactory;
+
+ public SemanticAnnotationPanel(
+ AbstractSemanticAnnotationContextualView semanticAnnotationContextualView,
+ SemanticAnnotationProfile semanticAnnotationProfile,
+ Set<Statement> statements, boolean allowChange) {
+ this.semanticAnnotationContextualView = semanticAnnotationContextualView;
+ this.semanticAnnotationProfile = semanticAnnotationProfile;
+ this.statements = statements;
+ this.allowChange = allowChange;
+ this.bestFactory = findBestPanelFactory();
+ initialise();
+ }
+
+ private void initialise() {
+ setLayout(new GridBagLayout());
+ // setBorder(new AbstractBorder() {
+ // @Override
+ // public void paintBorder(Component c, Graphics g, int x, int y, int
+ // width, int height) {
+ // g.setColor(Color.GRAY);
+ // g.drawLine(x, y+height-1, x+width-1, y+height-1);
+ // }
+ // });
+
+ GridBagConstraints c = new GridBagConstraints();
+ c.anchor = SOUTHEAST;
+ c.fill = BOTH;
+ c.weightx = 1;
+ c.gridx = 0;
+
+ OntProperty predicate = semanticAnnotationProfile.getPredicate();
+ c.gridwidth = 3;
+ JLabel label = new JLabel(format("Annotation type : %s",
+ getDisplayName(predicate)));
+ label.setBorder(new EmptyBorder(5, 5, 5, 5));
+ label.setBackground(WHITE);
+ label.setOpaque(true);
+ add(label, c);
+
+ c.insets = new Insets(7, 0, 0, 0);
+ c.anchor = EAST;
+ c.fill = HORIZONTAL;
+ if (statements.isEmpty()) {
+ c.gridwidth = 2;
+ // c.weightx = 1;
+ // c.gridy++;
+ add(new JLabel("No semantic annotations"), c);
+ } else {
+ c.gridwidth = 1;
+ for (Statement statement : statements) {
+ c.gridx = 0;
+ c.weightx = 1;
+ if (bestFactory != null) {
+ add(bestFactory.getDisplayComponent(
+ semanticAnnotationProfile, statement), c);
+ } else {
+ JTextArea value = new JTextArea(getObjectName(statement));
+ value.setLineWrap(true);
+ value.setWrapStyleWord(true);
+ value.setEditable(false);
+ value.setBackground(WHITE);
+ value.setOpaque(true);
+ value.setBorder(new EmptyBorder(2, 4, 2, 4));
+ add(value, c);
+ }
+ if (allowChange) {
+ c.gridx = 1;
+ c.weightx = 0;
+ add(createChangeButton(statement), c);
+
+ c.gridx = 2;
+ add(createDeleteButton(statement), c);
+ }
+ }
+ }
+
+ if (allowChange
+ && !enoughAlready(statements,
+ semanticAnnotationProfile.getMaxOccurs())) {
+ c.gridx = 0;
+ c.gridwidth = 3;
+ c.anchor = SOUTHEAST;
+ c.fill = NONE;
+ add(createAddButton(), c);
+ }
+ }
+
+ private boolean enoughAlready(Set<Statement> statements, Integer maxOccurs) {
+ return (maxOccurs != null) && (statements.size() >= maxOccurs);
+ }
+
+ private JButton createChangeButton(final Statement statement) {
+ return new DeselectingButton("Change", new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ addOrChangeAnnotation(statement);
+ }
+ });
+ }
+
+ private JButton createDeleteButton(final Statement statement) {
+ return new DeselectingButton("Delete", new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ semanticAnnotationContextualView.removeStatement(statement);
+ }
+ });
+ }
+
+ private JButton createAddButton() {
+ return new DeselectingButton("Add Annotation", new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ addOrChangeAnnotation(null);
+ }
+ });
+ }
+
+ private void addOrChangeAnnotation(Statement statement) {
+ JPanel annotationPanel = null;
+ JComponent inputComponent = null;
+
+ if (bestFactory != null) {
+ inputComponent = bestFactory.getInputComponent(
+ semanticAnnotationProfile, statement);
+ annotationPanel = getPropertyPanel(
+ getDisplayName(semanticAnnotationProfile.getPredicate()),
+ inputComponent);
+ }
+
+ if (annotationPanel == null) {
+ showMessageDialog(null, format("Unable to handle %s",
+ semanticAnnotationProfile.getPredicateString()),
+ "Annotation problem", ERROR_MESSAGE);
+ return;
+ }
+
+ int answer = showConfirmDialog(null, annotationPanel,
+ "Add/change annotation", OK_CANCEL_OPTION);
+ if (answer == OK_OPTION) {
+ RDFNode response = bestFactory.getNewTargetNode(statement,
+ inputComponent);
+ if (response == null)
+ return;
+ if (statement != null)
+ semanticAnnotationContextualView.changeStatement(statement,
+ semanticAnnotationProfile.getPredicate(), response);
+ else
+ semanticAnnotationContextualView.addStatement(
+ semanticAnnotationProfile.getPredicate(), response);
+ }
+ }
+
+ private PropertyPanelFactorySPI findBestPanelFactory() {
+ PropertyPanelFactorySPI result = null;
+ int currentRating = MIN_VALUE;
+ for (PropertyPanelFactorySPI factory : propertyPanelFactories) {
+ int ratingForSemanticAnnotation = factory
+ .getRatingForSemanticAnnotation(semanticAnnotationProfile);
+ if (ratingForSemanticAnnotation > currentRating) {
+ currentRating = ratingForSemanticAnnotation;
+ result = factory;
+ }
+ }
+ return result;
+ }
+
+ public static JPanel getPropertyPanel(String displayName,
+ Component inputComponent) {
+ JPanel result = new JPanel();
+ result.setLayout(new BorderLayout());
+ JPanel messagePanel = new JPanel(new BorderLayout());
+ messagePanel.setBorder(new EmptyBorder(5, 5, 0, 0));
+ messagePanel.setBackground(WHITE);
+ result.add(messagePanel, NORTH);
+
+ JLabel inputLabel = new JLabel("Enter a value for the annotation");
+ inputLabel.setBackground(WHITE);
+ Font baseFont = inputLabel.getFont();
+ inputLabel.setFont(baseFont.deriveFont(BOLD));
+ messagePanel.add(inputLabel, NORTH);
+
+ JTextArea messageText = new JTextArea(format(
+ "Enter a value for the annotation '%s'", displayName));
+ messageText.setMargin(new Insets(5, 10, 10, 10));
+ messageText.setMinimumSize(new Dimension(0, 30));
+ messageText.setFont(baseFont.deriveFont(11f));
+ messageText.setEditable(false);
+ messageText.setFocusable(false);
+ messagePanel.add(messageText, CENTER);
+
+ result.add(new JScrollPane(inputComponent), CENTER);
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/annotation/SemanticAnnotationUtils.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/annotation/SemanticAnnotationUtils.java b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/annotation/SemanticAnnotationUtils.java
new file mode 100644
index 0000000..68050c0
--- /dev/null
+++ b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/annotation/SemanticAnnotationUtils.java
@@ -0,0 +1,190 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package io.github.taverna_extras.component.ui.annotation;
+
+import static org.apache.jena.rdf.model.ModelFactory.createDefaultModel;
+import static org.apache.log4j.Logger.getLogger;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+import io.github.taverna_extras.component.api.ComponentException;
+import io.github.taverna_extras.component.api.profile.Profile;
+import io.github.taverna_extras.component.api.profile.SemanticAnnotationProfile;
+
+import org.apache.taverna.scufl2.api.annotation.Annotation;
+import org.apache.taverna.scufl2.api.common.AbstractNamed;
+import org.apache.taverna.scufl2.api.container.WorkflowBundle;
+
+import org.apache.jena.ontology.OntProperty;
+import org.apache.jena.ontology.OntResource;
+import org.apache.jena.rdf.model.Model;
+import org.apache.jena.rdf.model.RDFNode;
+import org.apache.jena.rdf.model.Resource;
+import org.apache.jena.rdf.model.Statement;
+
+/**
+ * @author David Withers
+ */
+public class SemanticAnnotationUtils {
+ protected static final String ENCODING = "TURTLE";
+ /* Pretend-base for making relative URIs */
+ private static String BASE = "widget://4aa8c93c-3212-487c-a505-3e337adf54a3/";
+ private static Logger logger = getLogger(SemanticAnnotationUtils.class);
+
+ public static String getObjectName(Statement statement) {
+ return getDisplayName(statement.getObject());
+ }
+
+ public static String getDisplayName(RDFNode node) {
+ if (node == null)
+ return "unknown";
+ else if (node.isAnon())
+ return "anon";
+ else if (node.isLiteral())
+ return node.asLiteral().getLexicalForm();
+ else if (node.isResource()) {
+ Resource resource = node.asResource();
+ if (resource instanceof OntResource) {
+ String label = ((OntResource) resource).getLabel(null);
+ if (label != null)
+ return label;
+ }
+ String localName = resource.getLocalName();
+ if ((localName != null) && !localName.isEmpty())
+ return localName;
+ return resource.toString();
+ } else
+ return "unknown";
+ }
+
+ public static Annotation findSemanticAnnotation(AbstractNamed annotated) {
+ for (Annotation annotation : annotated.getAnnotations())
+ return annotation;
+ return null;
+ }
+
+ public static String getStrippedAnnotationContent(Annotation annotation)
+ throws IOException {
+ AbstractNamed target = (AbstractNamed) annotation.getTarget();
+ return annotation.getRDFContent().replace(
+ target.getRelativeURI(annotation).toASCIIString(), BASE);
+ }
+
+ public static Annotation createSemanticAnnotation(WorkflowBundle bundle,
+ AbstractNamed target, Model model) throws IOException {
+ Calendar now = new GregorianCalendar();
+ Annotation annotation = new Annotation();
+ annotation.setParent(bundle);
+ String path = annotation.getResourcePath();
+ annotation.setTarget(target);
+ // annotation.setAnnotatedBy(annotatedBy);
+ annotation.setAnnotatedAt(now);
+ // annotation.setSerializedBy(serializedBy);
+ annotation.setSerializedAt(now);
+ bundle.getResources().addResource(
+ "@base<" + target.getRelativeURI(annotation).toASCIIString()
+ + "> .\n" + createTurtle(model), path, "text/rdf+n3");
+ return annotation;
+ }
+
+ /**
+ * @param model
+ * @return
+ */
+ public static String createTurtle(Model model) {
+ StringWriter stringWriter = new StringWriter();
+ model.write(stringWriter, ENCODING, BASE);
+ // Workaround for https://issues.apache.org/jira/browse/JENA-132
+ return stringWriter.toString().replace(BASE, "");
+ }
+
+ public static Model populateModel(WorkflowBundle annotated) {
+ Model result = createDefaultModel();
+ try {
+ for (Annotation a : annotated.getAnnotations())
+ populateModelFromString(result, a.getRDFContent());
+ } catch (Exception e) {
+ logger.error("failed to construct semantic annotation model", e);
+ }
+ return result;
+ }
+
+ public static void populateModel(Model result, Annotation annotation)
+ throws IOException {
+ AbstractNamed target = (AbstractNamed) annotation.getTarget();
+ String content = annotation.getRDFContent().replace(
+ target.getRelativeURI(annotation).toASCIIString(), BASE);
+ populateModelFromString(result, content);
+ }
+
+ public static void populateModelFromString(Model result, String content) {
+ result.read(new StringReader(content), BASE, ENCODING);
+ }
+
+ public static Resource createBaseResource(Model model) {
+ return model.createResource(BASE);
+ }
+
+ /**
+ * Check if a profile is satisfied by a component.
+ *
+ * @param bundle
+ * The component definition.
+ * @param componentProfile
+ * The profile definition.
+ * @return The set of failed constraints. If empty, the profile is satisfied
+ * by the component.
+ */
+ public static Set<SemanticAnnotationProfile> checkComponent(
+ WorkflowBundle bundle, Profile componentProfile) {
+ // TODO Check port presence by name
+ Set<SemanticAnnotationProfile> problemProfiles = new HashSet<>();
+ Model model = populateModel(bundle);
+ Set<Statement> statements = model.listStatements().toSet();
+ try {
+ for (SemanticAnnotationProfile saProfile : componentProfile
+ .getSemanticAnnotations()) {
+ OntProperty predicate = saProfile.getPredicate();
+ if (predicate == null)
+ continue;
+ int count = 0;
+ for (Statement statement : statements)
+ if (statement.getPredicate().equals(predicate))
+ count++;
+ if (count < saProfile.getMinOccurs())
+ problemProfiles.add(saProfile);
+ if (saProfile.getMaxOccurs() != null
+ && count > saProfile.getMaxOccurs())
+ // The UI should prevent this, but check anyway
+ problemProfiles.add(saProfile);
+ }
+ } catch (ComponentException e) {
+ logger.error("failed to look up profiles for semantic annotations", e);
+ }
+ return problemProfiles;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/annotation/TurtleContextualView.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/annotation/TurtleContextualView.java b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/annotation/TurtleContextualView.java
new file mode 100644
index 0000000..8489fe6
--- /dev/null
+++ b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/annotation/TurtleContextualView.java
@@ -0,0 +1,93 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package io.github.taverna_extras.component.ui.annotation;
+
+import static java.awt.BorderLayout.CENTER;
+import static io.github.taverna_extras.component.ui.annotation.SemanticAnnotationUtils.findSemanticAnnotation;
+import static io.github.taverna_extras.component.ui.annotation.SemanticAnnotationUtils.getStrippedAnnotationContent;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.awt.BorderLayout;
+import java.io.IOException;
+
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+
+import org.slf4j.Logger;
+
+import org.apache.taverna.scufl2.api.annotation.Annotation;
+import org.apache.taverna.scufl2.api.common.AbstractNamed;
+import org.apache.taverna.scufl2.api.container.WorkflowBundle;
+import org.apache.taverna.workbench.ui.views.contextualviews.ContextualView;
+
+/**
+ * @author alanrw
+ */
+public class TurtleContextualView extends ContextualView {
+ private static final long serialVersionUID = -3401885589263647202L;
+ private static final Logger log = getLogger(TurtleContextualView.class);
+ private JPanel panel;
+ private String annotationContent = "";
+
+ public TurtleContextualView(AbstractNamed selection, WorkflowBundle bundle) {
+ Annotation annotation = findSemanticAnnotation(selection);
+ try {
+ if (annotation != null)
+ annotationContent = getStrippedAnnotationContent(annotation);
+ } catch (IOException e) {
+ log.info("failed to read semantic annotation; using empty string", e);
+ }
+ initialise();
+ initView();
+ }
+
+ @Override
+ public JComponent getMainFrame() {
+ return panel;
+ }
+
+ @Override
+ public int getPreferredPosition() {
+ return 512;
+ }
+
+ @Override
+ public String getViewTitle() {
+ return "Turtle representation";
+ }
+
+ @Override
+ public void refreshView() {
+ initialise();
+ }
+
+ protected final void initialise() {
+ if (panel == null)
+ panel = new JPanel(new BorderLayout());
+ else
+ panel.removeAll();
+ JTextArea textArea = new JTextArea(20, 80);
+ textArea.setEditable(false);
+ textArea.setText(annotationContent);
+ panel.add(textArea, CENTER);
+ revalidate();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/annotation/TurtleInputPanel.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/annotation/TurtleInputPanel.java b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/annotation/TurtleInputPanel.java
new file mode 100644
index 0000000..7356cc9
--- /dev/null
+++ b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/annotation/TurtleInputPanel.java
@@ -0,0 +1,105 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package io.github.taverna_extras.component.ui.annotation;
+
+import static org.apache.jena.rdf.model.ModelFactory.createOntologyModel;
+import static java.awt.BorderLayout.CENTER;
+import static java.awt.BorderLayout.EAST;
+import static java.awt.BorderLayout.SOUTH;
+import static io.github.taverna_extras.component.ui.annotation.SemanticAnnotationUtils.populateModelFromString;
+
+import java.awt.BorderLayout;
+import java.awt.event.ActionEvent;
+import java.util.List;
+
+import javax.swing.AbstractAction;
+import javax.swing.JButton;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+
+import org.apache.jena.ontology.Individual;
+import org.apache.jena.ontology.OntClass;
+import org.apache.jena.ontology.OntModel;
+import org.apache.taverna.lang.ui.DeselectingButton;
+import org.apache.taverna.lang.ui.ReadOnlyTextArea;
+
+/**
+ * @author alanrw
+ */
+@SuppressWarnings("serial")
+public class TurtleInputPanel extends JPanel {
+ JTextArea turtleTextArea = new JTextArea(30, 80);
+ ReadOnlyTextArea errors = new ReadOnlyTextArea(1, 80);
+ private OntClass clazz;
+
+ public TurtleInputPanel(OntClass clazz) {
+ super(new BorderLayout());
+ this.clazz = clazz;
+
+ add(new JScrollPane(turtleTextArea), CENTER);
+
+ turtleTextArea.setText("<#changeme> a <" + clazz.getURI() + ">\n\n\n.");
+
+ JPanel buttonPanel = new JPanel();
+ buttonPanel.setLayout(new BorderLayout());
+ JButton validateButton = new DeselectingButton(new AbstractAction(
+ "Validate") {
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ getContentAsModel();
+ }
+ });
+ buttonPanel.add(errors, CENTER);
+ errors.setOpaque(false);
+ buttonPanel.add(validateButton, EAST);
+ add(buttonPanel, SOUTH);
+ }
+
+ public OntModel getContentAsModel() {
+ OntModel result = createOntologyModel();
+ try {
+ populateModelFromString(result, getContentAsString());
+
+ // Check it is not still called changeme
+ List<Individual> individuals = result.listIndividuals(clazz)
+ .toList();
+ if (individuals.isEmpty()) {
+ errors.setText("No valid individuals");
+ return null;
+ }
+ for (Individual i : individuals)
+ if (i.getURI().endsWith("changeme")) {
+ errors.setText("Name has not been changed");
+ return null;
+ }
+
+ errors.setText("No errors found");
+ return result;
+ } catch (Throwable ex) { // syntax error?
+ errors.setText(ex.getMessage());
+ return null;
+ }
+ }
+
+ public String getContentAsString() {
+ return turtleTextArea.getText();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/annotation/UnrecognizedStatementPanel.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/annotation/UnrecognizedStatementPanel.java b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/annotation/UnrecognizedStatementPanel.java
new file mode 100644
index 0000000..67d806d
--- /dev/null
+++ b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/annotation/UnrecognizedStatementPanel.java
@@ -0,0 +1,43 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package io.github.taverna_extras.component.ui.annotation;
+
+import static java.lang.String.format;
+
+import java.awt.BorderLayout;
+
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+import org.apache.jena.rdf.model.Statement;
+
+/**
+ * @author alanrw
+ *
+ */
+@SuppressWarnings("serial")
+public class UnrecognizedStatementPanel extends JPanel {
+ public UnrecognizedStatementPanel(Statement statement) {
+ setLayout(new BorderLayout());
+ setBorder(new GreyBorder());
+ add(new JLabel(format("Unable to find %s in the profile",
+ statement.getPredicate())));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/annotation/UnresolveablePredicatePanel.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/annotation/UnresolveablePredicatePanel.java b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/annotation/UnresolveablePredicatePanel.java
new file mode 100644
index 0000000..a7e2c89
--- /dev/null
+++ b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/annotation/UnresolveablePredicatePanel.java
@@ -0,0 +1,43 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package io.github.taverna_extras.component.ui.annotation;
+
+import static java.lang.String.format;
+
+import java.awt.BorderLayout;
+
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+import io.github.taverna_extras.component.api.profile.SemanticAnnotationProfile;
+
+/**
+ * @author alanrw
+ */
+@SuppressWarnings("serial")
+public class UnresolveablePredicatePanel extends JPanel {
+ public UnresolveablePredicatePanel(
+ SemanticAnnotationProfile semanticAnnotationProfile) {
+ setLayout(new BorderLayout());
+ setBorder(new GreyBorder());
+ add(new JLabel(format("Unable to resolve %s in the ontology",
+ semanticAnnotationProfile.getPredicateString())));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/config/ComponentConfigurationPanel.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/config/ComponentConfigurationPanel.java b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/config/ComponentConfigurationPanel.java
new file mode 100644
index 0000000..712b861
--- /dev/null
+++ b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/config/ComponentConfigurationPanel.java
@@ -0,0 +1,171 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package io.github.taverna_extras.component.ui.config;
+
+import static java.awt.event.ItemEvent.SELECTED;
+import static org.apache.log4j.Logger.getLogger;
+import static io.github.taverna_extras.component.api.config.ComponentPropertyNames.COMPONENT_NAME;
+import static io.github.taverna_extras.component.api.config.ComponentPropertyNames.COMPONENT_VERSION;
+import static io.github.taverna_extras.component.api.config.ComponentPropertyNames.FAMILY_NAME;
+import static io.github.taverna_extras.component.api.config.ComponentPropertyNames.REGISTRY_BASE;
+import static io.github.taverna_extras.component.ui.util.Utils.SHORT_STRING;
+
+import java.awt.GridBagConstraints;
+import java.awt.GridLayout;
+import java.awt.Insets;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.util.SortedMap;
+
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+
+import org.apache.log4j.Logger;
+import io.github.taverna_extras.component.api.Component;
+import io.github.taverna_extras.component.api.ComponentException;
+import io.github.taverna_extras.component.api.ComponentFactory;
+import io.github.taverna_extras.component.api.Version;
+import io.github.taverna_extras.component.ui.panel.ComponentListCellRenderer;
+
+import org.apache.taverna.scufl2.api.activity.Activity;
+import org.apache.taverna.services.ServiceRegistry;
+import org.apache.taverna.workbench.ui.views.contextualviews.activity.ActivityConfigurationPanel;
+
+@SuppressWarnings("serial")
+public class ComponentConfigurationPanel extends ActivityConfigurationPanel {
+ private static Logger logger = getLogger(ComponentConfigurationPanel.class);
+
+ private ComponentFactory factory;//FIXME beaninject
+ private ServiceRegistry sr;
+
+ private final JComboBox<Object> componentVersionChoice = new JComboBox<>();
+
+ public ComponentConfigurationPanel(Activity activity,
+ ComponentFactory factory, ServiceRegistry serviceRegistry) {
+ super(activity);
+ sr = serviceRegistry;
+ this.factory = factory;
+ componentVersionChoice.setPrototypeDisplayValue(SHORT_STRING);
+ initGui();
+ }
+
+ private Version getSelectedVersion() {
+ return (Version) componentVersionChoice.getSelectedItem();
+ }
+ private URI getRegistryBase() {
+ return URI.create(getProperty(REGISTRY_BASE));
+ }
+ private String getFamilyName() {
+ return getProperty(FAMILY_NAME);
+ }
+ private String getComponentName() {
+ return getProperty(COMPONENT_NAME);
+ }
+ private Integer getComponentVersion() {
+ return Integer.parseInt(getProperty(COMPONENT_VERSION));
+ }
+
+ protected void initGui() {
+ removeAll();
+ setLayout(new GridLayout(0, 2));
+
+ componentVersionChoice.setRenderer(new ComponentListCellRenderer<>());
+ componentVersionChoice.addItemListener(new ItemListener() {
+ @Override
+ public void itemStateChanged(ItemEvent event) {
+ if (event.getStateChange() == SELECTED)
+ updateToolTipText();
+ }
+ });
+ updateComponentVersionChoice();
+
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.insets = new Insets(0, 5, 0, 5);
+ gbc.gridx = 0;
+ gbc.anchor = GridBagConstraints.WEST;
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+ gbc.gridy = 2;
+ this.add(new JLabel("Component version:"), gbc);
+ gbc.gridx = 1;
+ gbc.weightx = 1;
+ this.add(componentVersionChoice, gbc);
+
+ // Populate fields from activity configuration bean
+ refreshConfiguration();
+ }
+
+ /**
+ * Check that user values in UI are valid
+ */
+ @Override
+ public boolean checkValues() {
+ return true;
+ }
+
+ /**
+ * Check if the user has changed the configuration from the original
+ */
+ @Override
+ public boolean isConfigurationChanged() {
+ return !getSelectedVersion().getVersionNumber().equals(
+ getComponentVersion());
+ }
+
+ /**
+ * Prepare a new configuration bean from the UI, to be returned with
+ * getConfiguration()
+ */
+ @Override
+ public void noteConfiguration() {
+ setProperty(COMPONENT_VERSION, getSelectedVersion().getVersionNumber()
+ .toString());
+ //FIXME is this right at all???
+ configureInputPorts(sr);
+ configureOutputPorts(sr);
+ }
+
+ private void updateComponentVersionChoice() {
+ Component component;
+ componentVersionChoice.removeAllItems();
+ componentVersionChoice.setToolTipText(null);
+ try {
+ component = factory.getComponent(getRegistryBase().toURL(),
+ getFamilyName(), getComponentName());
+ } catch (ComponentException | MalformedURLException e) {
+ logger.error("failed to get component", e);
+ return;
+ }
+ SortedMap<Integer, Version> componentVersionMap = component
+ .getComponentVersionMap();
+ for (Version v : componentVersionMap.values())
+ componentVersionChoice.addItem(v);
+ componentVersionChoice.setSelectedItem(componentVersionMap
+ .get(getComponentVersion()));
+ updateToolTipText();
+ }
+
+ private void updateToolTipText() {
+ Version selectedVersion = (Version) componentVersionChoice
+ .getSelectedItem();
+ componentVersionChoice.setToolTipText(selectedVersion.getDescription());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/config/ComponentConfigureAction.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/config/ComponentConfigureAction.java b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/config/ComponentConfigureAction.java
new file mode 100644
index 0000000..81c9d2f
--- /dev/null
+++ b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/config/ComponentConfigureAction.java
@@ -0,0 +1,69 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package io.github.taverna_extras.component.ui.config;
+
+import java.awt.Frame;
+import java.awt.event.ActionEvent;
+
+import io.github.taverna_extras.component.api.ComponentFactory;
+
+import org.apache.taverna.scufl2.api.activity.Activity;
+import org.apache.taverna.servicedescriptions.ServiceDescriptionRegistry;
+import org.apache.taverna.services.ServiceRegistry;
+import org.apache.taverna.workbench.activityicons.ActivityIconManager;
+import org.apache.taverna.workbench.edits.EditManager;
+import org.apache.taverna.workbench.file.FileManager;
+import org.apache.taverna.workbench.ui.actions.activity.ActivityConfigurationAction;
+import org.apache.taverna.workbench.ui.views.contextualviews.activity.ActivityConfigurationDialog;
+
+@SuppressWarnings("serial")
+public class ComponentConfigureAction extends ActivityConfigurationAction {
+ private EditManager editManager;
+ private FileManager fileManager;
+ private ServiceRegistry serviceRegistry;
+ private ComponentFactory factory;
+
+ public ComponentConfigureAction(Activity activity, Frame owner,
+ ComponentFactory factory, ActivityIconManager activityIconManager,
+ ServiceDescriptionRegistry serviceDescriptionRegistry,
+ EditManager editManager, FileManager fileManager,
+ ServiceRegistry serviceRegistry) {
+ super(activity, activityIconManager, serviceDescriptionRegistry);
+ this.editManager = editManager;
+ this.fileManager = fileManager;
+ this.serviceRegistry = serviceRegistry;
+ this.factory = factory;
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ ActivityConfigurationDialog currentDialog = getDialog(getActivity());
+ if (currentDialog != null) {
+ currentDialog.toFront();
+ return;
+ }
+
+ ComponentConfigurationPanel configView = new ComponentConfigurationPanel(
+ activity, factory, serviceRegistry);
+ ActivityConfigurationDialog dialog = new ActivityConfigurationDialog(
+ getActivity(), configView, editManager);
+ setDialog(getActivity(), dialog, fileManager);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/file/ComponentDataflowHealthCheckExplainer.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/file/ComponentDataflowHealthCheckExplainer.java b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/file/ComponentDataflowHealthCheckExplainer.java
new file mode 100644
index 0000000..7a2442f
--- /dev/null
+++ b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/file/ComponentDataflowHealthCheckExplainer.java
@@ -0,0 +1,91 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package io.github.taverna_extras.component.ui.file;
+
+import static java.util.Collections.sort;
+import static io.github.taverna_extras.component.ui.annotation.SemanticAnnotationUtils.getDisplayName;
+import static io.github.taverna_extras.component.ui.util.ComponentHealthCheck.FAILS_PROFILE;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Set;
+
+import javax.swing.JComponent;
+import javax.swing.JTextArea;
+
+import io.github.taverna_extras.component.api.profile.SemanticAnnotationProfile;
+import io.github.taverna_extras.component.ui.util.ComponentHealthCheck;
+import org.apache.taverna.visit.VisitKind;
+import org.apache.taverna.visit.VisitReport;
+
+//import net.sf.taverna.t2.workbench.report.explainer.VisitExplainer;
+
+/**
+ * @author alanrw
+ */
+public class ComponentDataflowHealthCheckExplainer implements VisitExplainer {
+ private static final Comparator<SemanticAnnotationProfile> comparator = new Comparator<SemanticAnnotationProfile>() {
+ @Override
+ public int compare(SemanticAnnotationProfile a,
+ SemanticAnnotationProfile b) {
+ return getDisplayName(a.getPredicate()).compareTo(
+ getDisplayName(b.getPredicate()));
+ }
+ };
+
+ @Override
+ public boolean canExplain(VisitKind vk, int resultId) {
+ return vk instanceof ComponentHealthCheck
+ && resultId == FAILS_PROFILE;
+ }
+
+ @Override
+ public JComponent getExplanation(VisitReport vr) {
+ @SuppressWarnings("unchecked")
+ Set<SemanticAnnotationProfile> problemProfiles = (Set<SemanticAnnotationProfile>) vr
+ .getProperty("problemProfiles");
+ List<SemanticAnnotationProfile> sortedList = new ArrayList<>(
+ problemProfiles);
+ sort(sortedList, comparator);
+ StringBuilder text = new StringBuilder();
+ for (SemanticAnnotationProfile profile : sortedList)
+ text.append(getSemanticProfileExplanation(profile)).append("\n");
+ return new JTextArea(text.toString());
+ }
+
+ @Override
+ public JComponent getSolution(VisitReport vr) {
+ return new JTextArea("Correct the semantic annotation");
+ }
+
+ private static String getSemanticProfileExplanation(
+ SemanticAnnotationProfile p) {
+ Integer minOccurs = p.getMinOccurs();
+ Integer maxOccurs = p.getMaxOccurs();
+ String displayName = getDisplayName(p.getPredicate());
+ if (maxOccurs == null)
+ return displayName + " must have at least " + minOccurs + " value";
+ if (minOccurs.equals(maxOccurs))
+ return displayName + " must have " + minOccurs + " value(s)";
+ return displayName + " must have between " + minOccurs + " and "
+ + maxOccurs + " value(s)";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/file/ComponentDataflowHealthChecker.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/file/ComponentDataflowHealthChecker.java b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/file/ComponentDataflowHealthChecker.java
new file mode 100644
index 0000000..7ce0c1b
--- /dev/null
+++ b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/file/ComponentDataflowHealthChecker.java
@@ -0,0 +1,114 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package io.github.taverna_extras.component.ui.file;
+
+import static org.apache.log4j.Logger.getLogger;
+import static io.github.taverna_extras.component.ui.annotation.SemanticAnnotationUtils.checkComponent;
+import static io.github.taverna_extras.component.ui.util.ComponentHealthCheck.FAILS_PROFILE;
+
+import java.util.List;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+import io.github.taverna_extras.component.api.ComponentException;
+import io.github.taverna_extras.component.api.ComponentFactory;
+import io.github.taverna_extras.component.api.Family;
+import io.github.taverna_extras.component.api.Version;
+import io.github.taverna_extras.component.api.profile.SemanticAnnotationProfile;
+import io.github.taverna_extras.component.ui.util.ComponentHealthCheck;
+
+import org.apache.taverna.scufl2.api.container.WorkflowBundle;
+import org.apache.taverna.visit.VisitReport;
+import static org.apache.taverna.visit.VisitReport.Status.SEVERE;
+import org.apache.taverna.workbench.file.FileManager;
+import org.apache.taverna.workflowmodel.Dataflow;
+import org.apache.taverna.workflowmodel.health.HealthChecker;
+
+/**
+ * @author alanrw
+ */
+public class ComponentDataflowHealthChecker implements HealthChecker<Dataflow> {
+ private static final String PROFILE_UNSATISFIED_MSG = "Workflow does not satisfy component profile";
+ private static Logger logger = getLogger(ComponentDataflowHealthChecker.class);
+
+ private FileManager fm;
+ private ComponentHealthCheck visitType = ComponentHealthCheck.getInstance(); //FIXME beaninject?
+ private ComponentFactory factory;
+
+ public void setComponentFactory(ComponentFactory factory) {
+ this.factory = factory;
+ }
+
+ public void setFileManager(FileManager fm) {
+ this.fm = fm;
+ }
+
+ private Version.ID getSource(Object o) {
+ return (Version.ID) fm.getDataflowSource((WorkflowBundle) o);
+ }
+
+ public void checkProfileSatisfied(WorkflowBundle bundle) {
+ //FIXME
+ }
+ @Override
+ public boolean canVisit(Object o) {
+ try {
+ return getSource(o) != null;
+ } catch (IllegalArgumentException e) {
+ // Not open?
+ } catch (ClassCastException e) {
+ // Not dataflow? Not component?
+ }
+ return false;
+ }
+
+ @Override
+ public VisitReport visit(WorkflowBundle dataflow, List<Object> ancestry) {
+ try {
+ Version.ID ident = getSource(dataflow);
+ Family family = factory.getFamily(ident.getRegistryBase(),
+ ident.getFamilyName());
+
+ Set<SemanticAnnotationProfile> problemProfiles = checkComponent(
+ dataflow, family.getComponentProfile());
+ if (problemProfiles.isEmpty())
+ return null;
+
+ VisitReport visitReport = new VisitReport(visitType, dataflow,
+ PROFILE_UNSATISFIED_MSG, FAILS_PROFILE, SEVERE);
+ visitReport.setProperty("problemProfiles", problemProfiles);
+ return visitReport;
+ } catch (ComponentException e) {
+ logger.error(
+ "failed to comprehend profile while checking for match", e);
+ return null;
+ }
+ }
+//
+// @Override
+// public VisitReport visit(Dataflow o, List<Object> ancestry) {
+// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+// }
+//
+// @Override
+// public boolean isTimeConsuming() {
+// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+// }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/file/ComponentOpener.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/file/ComponentOpener.java b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/file/ComponentOpener.java
new file mode 100644
index 0000000..f2e16e6
--- /dev/null
+++ b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/file/ComponentOpener.java
@@ -0,0 +1,88 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package io.github.taverna_extras.component.ui.file;
+
+import static org.apache.log4j.Logger.getLogger;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import io.github.taverna_extras.component.api.ComponentException;
+import io.github.taverna_extras.component.api.ComponentFactory;
+import io.github.taverna_extras.component.api.Version;
+import io.github.taverna_extras.component.api.Version.ID;
+
+import org.apache.taverna.scufl2.api.container.WorkflowBundle;
+import org.apache.taverna.workbench.file.AbstractDataflowPersistenceHandler;
+import org.apache.taverna.workbench.file.DataflowInfo;
+import org.apache.taverna.workbench.file.DataflowPersistenceHandler;
+import org.apache.taverna.workbench.file.FileType;
+import org.apache.taverna.workbench.file.exceptions.OpenException;
+
+/**
+ * @author alanrw
+ */
+public class ComponentOpener extends AbstractDataflowPersistenceHandler
+ implements DataflowPersistenceHandler {
+ private static Logger logger = getLogger(ComponentOpener.class);
+
+ private ComponentFactory factory;
+ private FileType fileType;
+
+ public void setComponentFactory(ComponentFactory factory) {
+ this.factory = factory;
+ }
+
+ public void setFileType(FileType fileType) {
+ this.fileType = fileType;
+ }
+
+ @Override
+ public DataflowInfo openDataflow(FileType fileType, Object source)
+ throws OpenException {
+ if (!getOpenFileTypes().contains(fileType))
+ throw new IllegalArgumentException("Unsupported file type "
+ + fileType);
+ if (!(source instanceof Version.ID))
+ throw new IllegalArgumentException("Unsupported source type "
+ + source.getClass().getName());
+
+ WorkflowBundle d;
+ try {
+ d = factory.getVersion((ID) source).getImplementation();
+ } catch (ComponentException e) {
+ logger.error("Unable to read dataflow", e);
+ throw new OpenException("Unable to read dataflow", e);
+ }
+ return new DataflowInfo(fileType, source, d, new Date());
+ }
+
+ @Override
+ public List<FileType> getOpenFileTypes() {
+ return Arrays.<FileType> asList(fileType);
+ }
+
+ @Override
+ public List<Class<?>> getOpenSourceTypes() {
+ return Arrays.<Class<?>> asList(Version.ID.class);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/file/ComponentSaver.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/file/ComponentSaver.java b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/file/ComponentSaver.java
new file mode 100644
index 0000000..19b52d9
--- /dev/null
+++ b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/file/ComponentSaver.java
@@ -0,0 +1,185 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package io.github.taverna_extras.component.ui.file;
+
+import static javax.swing.JOptionPane.OK_CANCEL_OPTION;
+import static javax.swing.JOptionPane.OK_OPTION;
+import static javax.swing.JOptionPane.showConfirmDialog;
+import static org.apache.log4j.Logger.getLogger;
+import static io.github.taverna_extras.component.ui.annotation.SemanticAnnotationUtils.checkComponent;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+
+import org.apache.log4j.Logger;
+import io.github.taverna_extras.component.api.Component;
+import io.github.taverna_extras.component.api.ComponentException;
+import io.github.taverna_extras.component.api.ComponentFactory;
+import io.github.taverna_extras.component.api.Family;
+import io.github.taverna_extras.component.api.Registry;
+import io.github.taverna_extras.component.api.Version;
+import io.github.taverna_extras.component.api.profile.SemanticAnnotationProfile;
+import io.github.taverna_extras.component.ui.serviceprovider.ComponentServiceProvider;
+
+import org.apache.taverna.scufl2.api.container.WorkflowBundle;
+import org.apache.taverna.scufl2.validation.ValidationReport;
+import org.apache.taverna.scufl2.validation.structural.StructuralValidator;
+import org.apache.taverna.workbench.file.AbstractDataflowPersistenceHandler;
+import org.apache.taverna.workbench.file.DataflowInfo;
+import org.apache.taverna.workbench.file.DataflowPersistenceHandler;
+import org.apache.taverna.workbench.file.FileType;
+import org.apache.taverna.workbench.file.exceptions.SaveException;
+
+/**
+ * @author alanrw
+ */
+public class ComponentSaver extends AbstractDataflowPersistenceHandler
+ implements DataflowPersistenceHandler {
+ private static final String UNSATISFIED_PROFILE_WARNING = "The component does not satisfy the profile.\n"
+ + "See validation report.\nDo you still want to save?";
+ private static final Logger logger = getLogger(ComponentSaver.class);
+
+ private ComponentFactory factory;
+ private ComponentServiceProvider provider;
+ private FileType cft;
+
+ public void setComponentFactory(ComponentFactory factory) {
+ this.factory = factory;
+ }
+
+ public void setFileType(FileType fileType) {
+ this.cft = fileType;
+ }
+
+ public void setServiceProvider(ComponentServiceProvider provider) {
+ this.provider = provider;
+ }
+
+ @Override
+ public DataflowInfo saveDataflow(WorkflowBundle bundle, FileType fileType,
+ Object destination) throws SaveException {
+ if (!getSaveFileTypes().contains(fileType))
+ throw new IllegalArgumentException("Unsupported file type "
+ + fileType);
+ if (!(destination instanceof Version.ID))
+ throw new IllegalArgumentException("Unsupported destination type "
+ + destination.getClass().getName());
+
+ ValidationReport structuralValidity = new StructuralValidator()
+ .validate(bundle);
+ if (structuralValidity.detectedProblems())
+ throw new SaveException(
+ "Cannot save a structurally invalid workflow as a component",
+ structuralValidity.getException());
+
+ /*
+ * Saving an invalid dataflow is OK. Validity check is done to get
+ * predicted depth for output (if possible)
+ */
+
+ Version.ID ident = (Version.ID) destination;
+
+ if (ident.getComponentVersion() == -1) {
+ Version.ID newIdent = new Version.Identifier(
+ ident.getRegistryBase(), ident.getFamilyName(),
+ ident.getComponentName(), 0);
+ return new DataflowInfo(cft, newIdent, bundle);
+ }
+
+ Family family;
+ try {
+ Registry registry = factory.getRegistry(ident.getRegistryBase());
+ family = registry.getComponentFamily(ident.getFamilyName());
+ } catch (ComponentException e) {
+ throw new SaveException("Unable to read component", e);
+ }
+
+ Version newVersion = null;
+ try {
+ List<SemanticAnnotationProfile> problemProfiles = new ArrayList<>(
+ checkComponent(bundle, family.getComponentProfile()));
+
+ if (!problemProfiles.isEmpty()) {
+ int answer = showConfirmDialog(null,
+ UNSATISFIED_PROFILE_WARNING, "Profile problem",
+ OK_CANCEL_OPTION);
+ if (answer != OK_OPTION)
+ throw new SaveException("Saving cancelled");
+ }
+
+ JTextArea descriptionArea = new JTextArea(10, 60);
+ descriptionArea.setLineWrap(true);
+ descriptionArea.setWrapStyleWord(true);
+ final JScrollPane descriptionScrollPane = new JScrollPane(
+ descriptionArea);
+ if (ident.getComponentVersion() == 0) {
+ int answer = showConfirmDialog(null, descriptionScrollPane,
+ "Component description", OK_CANCEL_OPTION);
+ if (answer != OK_OPTION)
+ throw new SaveException("Saving cancelled");
+ newVersion = family.createComponentBasedOn(
+ ident.getComponentName(), descriptionArea.getText(),
+ bundle);
+ } else {
+ Component component = family.getComponent(ident
+ .getComponentName());
+ int answer = showConfirmDialog(null, descriptionScrollPane,
+ "Version description", OK_CANCEL_OPTION);
+ if (answer != OK_OPTION)
+ throw new SaveException("Saving cancelled");
+ newVersion = component.addVersionBasedOn(bundle,
+ descriptionArea.getText());
+ }
+ } catch (ComponentException e) {
+ logger.error("Unable to save new version of component", e);
+ throw new SaveException("Unable to save new version of component",
+ e);
+ }
+
+ Version.ID newIdent = new Version.Identifier(ident.getRegistryBase(),
+ ident.getFamilyName(), ident.getComponentName(),
+ newVersion.getVersionNumber());
+ provider.refreshProvidedComponent(ident);
+ return new DataflowInfo(cft, newIdent, bundle);
+ }
+
+ @Override
+ public List<FileType> getSaveFileTypes() {
+ return Arrays.<FileType> asList(cft);
+ }
+
+ @Override
+ public List<Class<?>> getSaveDestinationTypes() {
+ return Arrays.<Class<?>> asList(Version.ID.class);
+ }
+
+ @Override
+ public boolean wouldOverwriteDataflow(WorkflowBundle dataflow,
+ FileType fileType, Object destination, DataflowInfo lastDataflowInfo) {
+ if (!getSaveFileTypes().contains(fileType))
+ throw new IllegalArgumentException("Unsupported file type "
+ + fileType);
+ return false;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/file/FileManagerObserver.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/file/FileManagerObserver.java b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/file/FileManagerObserver.java
new file mode 100644
index 0000000..8ee99b9
--- /dev/null
+++ b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/file/FileManagerObserver.java
@@ -0,0 +1,146 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package io.github.taverna_extras.component.ui.file;
+
+import static java.awt.Color.WHITE;
+import static java.awt.Font.BOLD;
+import static javax.swing.SwingUtilities.invokeLater;
+import static javax.swing.SwingUtilities.isEventDispatchThread;
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Insets;
+
+import javax.swing.border.Border;
+
+import org.apache.batik.swing.JSVGCanvas;
+import io.github.taverna_extras.component.api.Version;
+import io.github.taverna_extras.component.ui.util.Utils;
+import org.apache.taverna.lang.observer.Observable;
+import org.apache.taverna.lang.observer.Observer;
+
+import org.apache.taverna.scufl2.api.container.WorkflowBundle;
+import org.apache.taverna.workbench.StartupSPI;
+import org.apache.taverna.workbench.configuration.colour.ColourManager;
+import org.apache.taverna.workbench.file.FileManager;
+import org.apache.taverna.workbench.file.events.FileManagerEvent;
+import org.apache.taverna.workbench.models.graph.svg.SVGGraphController;
+import org.apache.taverna.workbench.views.graph.GraphViewComponent;
+
+public class FileManagerObserver implements StartupSPI {
+ private static final Color COLOR = new Color(230, 147, 210);
+
+ private FileManager fileManager;
+ private ColourManager colours;
+ private GraphViewComponent graphView;
+ private Utils utils;
+
+ public void setFileManager(FileManager fileManager) {
+ this.fileManager = fileManager;
+ }
+
+ public void setColourManager(ColourManager colours) {
+ this.colours = colours;
+ }
+
+ public void setGraphView(GraphViewComponent graphView) {
+ this.graphView = graphView;
+ }
+
+ public void setUtils(Utils utils) {
+ this.utils = utils;
+ }
+
+ @Override
+ public boolean startup() {
+ colours.setPreferredColour(
+ "io.github.taverna_extras.component.registry.Component", COLOR);
+ colours.setPreferredColour(
+ "io.github.taverna_extras.component.ComponentActivity", COLOR);
+ fileManager.addObserver(new Observer<FileManagerEvent>() {
+ @Override
+ public void notify(Observable<FileManagerEvent> observable,
+ FileManagerEvent event) throws Exception {
+ FileManagerObserverRunnable runnable = new FileManagerObserverRunnable();
+ if (isEventDispatchThread())
+ runnable.run();
+ else
+ invokeLater(runnable);
+ }
+ });
+ return true;
+ }
+
+ @Override
+ public int positionHint() {
+ return 200;
+ }
+
+ public class FileManagerObserverRunnable implements Runnable {
+ @Override
+ public void run() {
+ WorkflowBundle currentDataflow = fileManager.getCurrentDataflow();
+ if (currentDataflow == null)
+ return;
+ SVGGraphController graphController = (SVGGraphController) graphView
+ .getGraphController(currentDataflow.getMainWorkflow());
+ if (graphController == null)
+ return;
+ JSVGCanvas svgCanvas = graphController.getSVGCanvas();
+ Object dataflowSource = fileManager
+ .getDataflowSource(currentDataflow);
+ if (utils.currentDataflowIsComponent())
+ svgCanvas.setBorder(new ComponentBorder(
+ (Version.ID) dataflowSource));
+ else
+ svgCanvas.setBorder(null);
+ svgCanvas.repaint();
+ }
+ }
+
+ static class ComponentBorder implements Border {
+ private final Insets insets = new Insets(25, 0, 0, 0);
+ private final String text;
+
+ public ComponentBorder(Version.ID identification) {
+ text = "Component : " + identification.getComponentName();
+ }
+
+ @Override
+ public Insets getBorderInsets(java.awt.Component c) {
+ return insets;
+ }
+
+ @Override
+ public boolean isBorderOpaque() {
+ return true;
+ }
+
+ @Override
+ public void paintBorder(java.awt.Component c, Graphics g, int x, int y,
+ int width, int height) {
+ g.setColor(COLOR);
+ g.fillRect(x, y, width, 20);
+ g.setFont(g.getFont().deriveFont(BOLD));
+ g.setColor(WHITE);
+ g.drawString(text, x + 5, y + 15);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/localworld/LocalWorld.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/localworld/LocalWorld.java b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/localworld/LocalWorld.java
new file mode 100644
index 0000000..a35ab61
--- /dev/null
+++ b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/localworld/LocalWorld.java
@@ -0,0 +1,107 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package io.github.taverna_extras.component.ui.localworld;
+
+import static org.apache.jena.rdf.model.ModelFactory.createOntologyModel;
+import static org.apache.log4j.Logger.getLogger;
+import static io.github.taverna_extras.component.ui.annotation.SemanticAnnotationUtils.createTurtle;
+import static io.github.taverna_extras.component.ui.annotation.SemanticAnnotationUtils.populateModelFromString;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import org.apache.jena.ontology.Individual;
+import org.apache.jena.ontology.OntClass;
+import org.apache.jena.ontology.OntModel;
+import org.apache.jena.rdf.model.Resource;
+import org.apache.taverna.configuration.app.ApplicationConfiguration;
+
+/**
+ * @author alanrw
+ */
+public class LocalWorld {
+ private static final String FILENAME = "localWorld.ttl";
+ private static final Logger logger = getLogger(LocalWorld.class);
+ protected static final String ENCODING = "TURTLE";
+ private static LocalWorld instance = null;
+
+ private OntModel model;
+
+ public synchronized static LocalWorld getInstance() {
+ if (instance == null)
+ instance = new LocalWorld();
+ return instance;
+ }
+
+ private LocalWorld() {
+ File modelFile = new File(calculateComponentsDirectory(), FILENAME);
+ model = createOntologyModel();
+ if (modelFile.exists())
+ try (Reader in = new InputStreamReader(new FileInputStream(
+ modelFile), "UTF-8")) {
+ model.read(in, null, ENCODING);
+ } catch (IOException e) {
+ logger.error("failed to construct local annotation world", e);
+ }
+ }
+
+ ApplicationConfiguration config;//FIXME beaninject
+
+ public File calculateComponentsDirectory() {
+ return new File(config.getApplicationHomeDir(), "components");
+ }
+
+ public Individual createIndividual(String urlString, OntClass rangeClass) {
+ try {
+ return model.createIndividual(urlString, rangeClass);
+ } finally {
+ saveModel();
+ }
+ }
+
+ private void saveModel() {
+ File modelFile = new File(calculateComponentsDirectory(), FILENAME);
+ try (OutputStream out = new FileOutputStream(modelFile)) {
+ out.write(createTurtle(model).getBytes("UTF-8"));
+ } catch (IOException e) {
+ logger.error("failed to save local annotation world", e);
+ }
+ }
+
+ public List<Individual> getIndividualsOfClass(Resource clazz) {
+ return model.listIndividuals(clazz).toList();
+ }
+
+ public void addModelFromString(String addedModel) {
+ try {
+ populateModelFromString(model, addedModel);
+ } finally {
+ saveModel();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/menu/AbstractContextComponentMenuAction.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/menu/AbstractContextComponentMenuAction.java b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/menu/AbstractContextComponentMenuAction.java
new file mode 100644
index 0000000..0911a66
--- /dev/null
+++ b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/menu/AbstractContextComponentMenuAction.java
@@ -0,0 +1,58 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package io.github.taverna_extras.component.ui.menu;
+
+import java.net.URI;
+
+import io.github.taverna_extras.component.api.config.ComponentConfig;
+
+import org.apache.taverna.scufl2.api.activity.Activity;
+import org.apache.taverna.scufl2.api.core.Processor;
+import org.apache.taverna.ui.menu.AbstractContextualMenuAction;
+
+public abstract class AbstractContextComponentMenuAction extends AbstractContextualMenuAction {
+ public AbstractContextComponentMenuAction(URI parentId, int positionHint) {
+ super(parentId, positionHint);
+ }
+
+ public AbstractContextComponentMenuAction(URI parentId, int positionHint, URI id) {
+ super(parentId, positionHint, id);
+ }
+
+ protected boolean isComponentActivity(Activity act) {
+ if (act == null)
+ return false;
+ return act.getType().equals(ComponentConfig.URI);
+ }
+
+ protected Activity findActivity() {
+ if (getContextualSelection() == null)
+ return null;
+ Object selection = getContextualSelection().getSelection();
+ if (selection instanceof Processor) {
+ Processor processor = (Processor) selection;
+ return processor.getParent().getParent().getMainProfile()
+ .getProcessorBindings().getByName(processor.getName())
+ .getBoundActivity();
+ } else if (selection instanceof Activity)
+ return (Activity) selection;
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/menu/ComponentConfigureMenuAction.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/menu/ComponentConfigureMenuAction.java b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/menu/ComponentConfigureMenuAction.java
new file mode 100644
index 0000000..0feb63e
--- /dev/null
+++ b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/menu/ComponentConfigureMenuAction.java
@@ -0,0 +1,81 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package io.github.taverna_extras.component.ui.menu;
+
+import static javax.swing.Action.NAME;
+import static io.github.taverna_extras.component.ui.ComponentConstants.ACTIVITY_URI;
+
+import javax.swing.Action;
+
+import io.github.taverna_extras.component.api.ComponentFactory;
+import io.github.taverna_extras.component.ui.config.ComponentConfigureAction;
+import org.apache.taverna.servicedescriptions.ServiceDescriptionRegistry;
+import org.apache.taverna.services.ServiceRegistry;
+import org.apache.taverna.workbench.activityicons.ActivityIconManager;
+import org.apache.taverna.workbench.activitytools.AbstractConfigureActivityMenuAction;
+import org.apache.taverna.workbench.edits.EditManager;
+import org.apache.taverna.workbench.file.FileManager;
+
+public class ComponentConfigureMenuAction extends
+ AbstractConfigureActivityMenuAction {
+ public ComponentConfigureMenuAction() {
+ super(ACTIVITY_URI);
+ }
+
+ private ActivityIconManager aim;
+ private ServiceDescriptionRegistry sdr;
+ private EditManager em;
+ private FileManager fm;
+ private ServiceRegistry str;
+ private ComponentFactory factory;
+
+ public void setActivityIconManager(ActivityIconManager aim) {
+ this.aim = aim;
+ }
+
+ public void setServiceDescriptionRegistry(ServiceDescriptionRegistry sdr) {
+ this.sdr = sdr;
+ }
+
+ public void setEditManager(EditManager em) {
+ this.em = em;
+ }
+
+ public void setFileManager(FileManager fm) {
+ this.fm = fm;
+ }
+
+ public void setServiceTypeRegistry(ServiceRegistry str) {
+ this.str = str;
+ }
+
+ public void setComponentFactory(ComponentFactory factory) {
+ this.factory = factory;
+ }
+
+ @Override
+ protected Action createAction() {
+ Action result = new ComponentConfigureAction(findActivity(),
+ getParentFrame(), factory, aim, sdr, em, fm, str);
+ result.putValue(NAME, "Configure component");
+ addMenuDots(result);
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/menu/ComponentMenu.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/menu/ComponentMenu.java b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/menu/ComponentMenu.java
new file mode 100644
index 0000000..99cec65
--- /dev/null
+++ b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/menu/ComponentMenu.java
@@ -0,0 +1,41 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package io.github.taverna_extras.component.ui.menu;
+
+import java.net.URI;
+import org.apache.taverna.ui.menu.AbstractMenu;
+import static org.apache.taverna.ui.menu.DefaultMenuBar.DEFAULT_MENU_BAR;
+
+/**
+ * @author alanrw
+ */
+public class ComponentMenu extends AbstractMenu {
+ public static final URI COMPONENT = URI
+ .create("http://taverna.sf.net/2008/t2workbench/menu#component");
+ public static final String TITLE = "Components";
+
+ public ComponentMenu() {
+ super(DEFAULT_MENU_BAR, 950, COMPONENT, makeAction());
+ }
+
+ public static DummyAction makeAction() {
+ return new DummyAction(TITLE);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/menu/ComponentSection.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/menu/ComponentSection.java b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/menu/ComponentSection.java
new file mode 100644
index 0000000..337ee73
--- /dev/null
+++ b/taverna-component-activity-ui/src/main/java/io/github/taverna_extras/component/ui/menu/ComponentSection.java
@@ -0,0 +1,44 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package io.github.taverna_extras.component.ui.menu;
+
+import java.net.URI;
+import org.apache.taverna.ui.menu.AbstractMenuSection;
+
+/**
+ * @author alanrw
+ *
+ */
+public class ComponentSection extends AbstractMenuSection {
+ public static final String COMPONENT_SECTION = "Components";
+ public static final URI componentSection = URI
+ .create("http://taverna.sf.net/2009/contextMenu/components");
+ public static final URI editSection = URI
+ .create("http://taverna.sf.net/2009/contextMenu/edit");
+
+ public ComponentSection() {
+ super(editSection, 100, componentSection);
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return super.isEnabled();
+ }
+}