/* * This software is Copyright 2005,2006,2007,2008 Langdale Consultants. * Langdale Consultants can be contacted at: http://www.langdale.com.au */ package au.com.langdale.cimtoole.editors.profile; import static au.com.langdale.ui.builder.Templates.CheckBox; import static au.com.langdale.ui.builder.Templates.CheckboxTreeViewer; import static au.com.langdale.ui.builder.Templates.Form; import static au.com.langdale.ui.builder.Templates.Column; import static au.com.langdale.ui.builder.Templates.Span; import static au.com.langdale.ui.builder.Templates.PushButton; import static au.com.langdale.ui.builder.Templates.Row; import static au.com.langdale.ui.builder.Templates.Field; import static au.com.langdale.ui.builder.Templates.Label; import static au.com.langdale.ui.builder.Templates.Stack; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import au.com.langdale.cimtoole.editors.ProfileEditor; import au.com.langdale.jena.JenaCheckTreeBinding; import au.com.langdale.jena.TreeModelBase; import au.com.langdale.jena.TreeModelBase.Node; import au.com.langdale.kena.OntResource; import au.com.langdale.profiles.HierarchyModel; import au.com.langdale.profiles.ProfileClass; import au.com.langdale.profiles.ProfileModel; import au.com.langdale.profiles.ProfileModel.GeneralTypeNode; import au.com.langdale.profiles.ProfileModel.NaturalNode.ElementNode; import au.com.langdale.profiles.ProfileModel.TypeNode; import au.com.langdale.profiles.Refactory; import au.com.langdale.profiles.ProfileModel.Cardinality; import au.com.langdale.profiles.ProfileModel.NaturalNode; import au.com.langdale.ui.builder.FurnishedEditor; import au.com.langdale.ui.builder.Template; import au.com.langdale.ui.util.IconCache; import au.com.langdale.xmi.UML; public class Hierarchy extends FurnishedEditor { private ProfileEditor master; private SuperClassBinding bases; private UnionBinding assoc; public Hierarchy(String name, ProfileEditor master) { super(name); this.master = master; bases = new SuperClassBinding(); assoc = new UnionBinding(); } public abstract class TypeBinding extends JenaCheckTreeBinding { public TypeBinding(HierarchyModel tree) { super(tree); setRootVisible(false); } protected abstract boolean isEnabled(); protected abstract Set findRelated(); protected abstract void addRelated(OntResource related); protected abstract void removeRelated(OntResource related); protected HierarchyModel getHierarchyModel() { return (HierarchyModel) getTree(); } @Override public void refresh() { if(isEnabled()) { super.refresh(); getCheckViewer().getTree().setVisible(true); getCheckViewer().expandAll(); } else { getCheckViewer().getTree().setVisible(false); } } @Override public void update() { if( isEnabled()) super.update(); } private Set related; @Override protected void fillChecks() { related = findRelated(); super.fillChecks(); } @Override protected boolean toBeChecked(Node node) { return related.contains(node.getSubject()); } @Override protected void fetchChecks() { preFetchChecks(); super.fetchChecks(); postFetchChecks(); } private Set new_related; private void preFetchChecks() { new_related = new HashSet(); } @Override protected void hasBeenChecked(Node node) { new_related.add(node.getSubject()); } private void postFetchChecks() { related = findRelated(); for (Iterator it = related.iterator(); it.hasNext();) { OntResource clss = (OntResource) it.next(); if( ! new_related.contains(clss)) removeRelated(clss); } for (Iterator it = new_related.iterator(); it.hasNext();) { OntResource clss = (OntResource) it.next(); if( ! related.contains(clss)) addRelated(clss); } } } public class SuperClassBinding extends TypeBinding { public SuperClassBinding() { super( new HierarchyModel(false)); } @Override protected void fillTree() { getHierarchyModel().setRefactory(getTarget().getProfileModel().getRefactory()); getHierarchyModel().setRootResource(getTarget().getBaseClass()); } protected boolean isEnabled() { return master.getNode() instanceof NaturalNode; } private NaturalNode getTarget() { return (NaturalNode) (isEnabled()? master.getNode(): null); } protected Set findRelated() { return Refactory.asSet(getTarget().getProfile().getSuperClasses()); } protected void addRelated(OntResource related) { if( ! getTarget().getSubject().equals(related)) getTarget().getProfile().addSuperClass(related); } protected void removeRelated(OntResource related) { getTarget().getProfile().removeSuperClass(related); } } public class UnionBinding extends TypeBinding { public UnionBinding() { super( new HierarchyModel(true)); } @Override protected void fillTree() { getHierarchyModel().setRefactory(getTarget().getProfileModel().getRefactory()); getHierarchyModel().setRootResource(getTarget().getBaseClass()); } public boolean isEnabled() { return master.getNode() instanceof ElementNode; } private ElementNode getTarget() { return (ElementNode) (isEnabled()? master.getNode(): null); } @Override protected Set findRelated() { Set result = new HashSet(); for( Object member: getTarget().getProfile().getUnionMembers()) result.add(((ProfileClass)member).getSubject()); return result; } @Override protected void addRelated(OntResource related) { getTarget().getProfile().addUnionMember(related); } @Override protected void removeRelated(OntResource related) { getTarget().getProfile().removeUnionMember(related); } } @Override protected Content createContent() { return new Content(master.getToolkit()) { @Override protected Template define() { return Form( Stack( Column( Stack( Span( Label("class", "Restrict this class."), CheckBox("concrete", "Make this class concrete") ), Span( Label("prop", "Restrict this property."), CheckBox("reference", "By Reference") ) ), Span( Label("card", "Min"), Row(Field("minimum")), Label("Max"), Row(Field("maximum")), Row( CheckBox("require", "At least one"), CheckBox("single", "At most one"), CheckBox("unbounded", "Unbounded")) ), Stack( Column( Label("Select Super Class:"), CheckboxTreeViewer("bases") ), Column( Label("Select Associated Class or Classes:"), CheckboxTreeViewer("assoc", true) ), Label("datatype", "Datatype") ) ), Span( Label("nothing", "Select a class or property to restrict or "), PushButton("jump", "Goto Add/Remove Page") ) ) ); } private void bindTree( JenaCheckTreeBinding binding, String name) { binding.bind(name, this); TreeViewer viewer = getTreeViewer(name); master.listenToDoubleClicks(viewer); master.listenToSelection(viewer); } @Override protected void addBindings() { bindTree(bases, "bases"); bindTree(assoc, "assoc"); addListener("jump", jump); } private final SelectionListener jump = new SelectionListener() { public void widgetSelected(SelectionEvent e) { master.setActivePageByName("Add/Remove"); } public void widgetDefaultSelected(SelectionEvent e) { } }; @Override public void refresh() { Node node = master.getNode(); getForm().setImage(IconCache.getIcons().get(node)); getForm().setText(master.getComment()); if(node instanceof ElementNode) { showStackLayer("prop"); ElementNode enode = (ElementNode)node; if(enode.isDatatype() ) { setTextValue("datatype", "Datatype is " + TreeModelBase.label(enode.getBase().getRange())); showStackLayer("datatype"); } else { showStackLayer("assoc"); } setButtonValue("reference", enode.isReference()).setEnabled(! enode.isDatatype()); refreshCardinality(enode); } else if( node instanceof GeneralTypeNode ) { GeneralTypeNode tnode = (GeneralTypeNode)node; if( ! tnode.isEnumerated()) { showStackLayer("class"); showStackLayer("bases"); boolean concrete = tnode.hasStereotype(UML.concrete); setButtonValue("concrete", concrete).setEnabled(tnode.getSubject().isURIResource()); refreshCardinality(tnode); } else showStackLayer("nothing"); } else showStackLayer("nothing"); } @Override public void update() { Node node = master.getNode(); if( node instanceof ElementNode) { ElementNode enode = (ElementNode) node; enode.setReference(getButton("reference").getSelection()); updateCardinality(enode); } else if(node instanceof TypeNode) { TypeNode tnode = (TypeNode) node; boolean selection = getButton("concrete").getSelection(); if( ! selection ) { tnode.setMinCardinality(0); tnode.setMaxCardinality(Integer.MAX_VALUE); } tnode.setStereotype(UML.concrete, selection); if( selection ) updateCardinality(tnode); } node.structureChanged(); } private void refreshCardinality(Cardinality cnode) { setButtonValue("single", (cnode.getMaxCardinality() == 1)).setEnabled(cnode.isMaxVariable()); setButtonValue("require", (cnode.getMinCardinality() > 0)).setEnabled(cnode.isMinVariable()); setButtonValue("unbounded", (cnode.getMaxCardinality() == Integer.MAX_VALUE)).setEnabled(cnode.isMaxVariable()); setTextValue("minimum", ProfileModel.cardString(cnode.getMinCardinality())).setEnabled(cnode.isMinVariable()); setTextValue("maximum", ProfileModel.cardString(cnode.getMaxCardinality())).setEnabled(cnode.isMaxVariable()); } private void updateCardinality(Cardinality node) { int max = node.getMaxCardinality(); int min = node.getMinCardinality(); int newMax, newMin; try { newMax = ProfileModel.cardInt(getText("maximum").getText()); newMin = ProfileModel.cardInt(getText("minimum").getText()); } catch( NumberFormatException e) { return; } if( newMax == max ) { if(getButton("single").getSelection()) newMax = 1; else if( max == 1 ) newMax = Integer.MAX_VALUE; } if( newMax == max ) { if(getButton("unbounded").getSelection()) newMax = Integer.MAX_VALUE; else if (max == Integer.MAX_VALUE) newMax = 1; } if( newMin == min ) { if(! getButton("require").getSelection()) newMin = 0; else if( min == 0 ) newMin = 1; } node.setMaxCardinality(newMax); node.setMinCardinality(newMin); } }; } }