-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.mapping.pattern;\r
-\r
-\r
-public class MappingRule {\r
- /*\r
- static final THashSet<Resource> EMPTY_SET = new THashSet<Resource>();\r
- \r
- THashMap<Resource, Resource> resourcesByDomains = new THashMap<Resource, Resource>();\r
- Collection<IConstraint> constraints = new ArrayList<IConstraint>();\r
- Collection<ConstraintGroup> constraintGroups = new ArrayList<ConstraintGroup>();\r
- \r
- static class ConstraintGroup {\r
- Collection<IConstraint> constraints;\r
- Collection<Resource> targets;\r
- Collection<Resource> dependencies;\r
- }\r
- \r
- class DirectedRuleBuilder {\r
- THashSet<Resource> sourceResources = new THashSet<Resource>();\r
- THashSet<Resource> targetResources = new THashSet<Resource>();\r
- THashSet<IConstraint> sourceConstraints = new THashSet<IConstraint>();\r
- THashSet<IConstraint> targetConstraints = new THashSet<IConstraint>();\r
- TObjectIntHashMap<Resource> boundResources;\r
- int id;\r
- \r
- Instruction root = new DummyInstruction();\r
- Instruction cur = root;\r
- \r
- public DirectedRuleBuilder(final THashSet<Resource> sourceDomains,\r
- TObjectIntHashMap<Resource> boundResources, int id) {\r
- this.boundResources = boundResources;\r
- this.id = id;\r
- \r
- // Classify resources\r
- \r
- resourcesByDomains.forEachEntry(new TObjectObjectProcedure<Resource, Resource>() {\r
-\r
- @Override\r
- public boolean execute(Resource domain, Resource resource) {\r
- if(sourceDomains.contains(domain))\r
- sourceResources.add(resource);\r
- else\r
- targetResources.add(resource);\r
- return true;\r
- }\r
- \r
- });\r
- \r
- // Classify constraints \r
- \r
- for(IConstraint constraint : constraints) {\r
- if(sourceResources.containsAll(constraint.binds()))\r
- sourceConstraints.add(constraint);\r
- else\r
- targetConstraints.add(constraint);\r
- }\r
- } \r
- \r
- int bestValue;\r
- IConstraint bestConstraint;\r
- \r
- private void findBestConstraint(THashSet<IConstraint> constraints) {\r
- bestValue = 0;\r
- bestConstraint = null;\r
- sourceConstraints.forEach(new TObjectProcedure<IConstraint>() {\r
- \r
- @Override\r
- public boolean execute(IConstraint constraint) {\r
- int temp = constraint.isApplicable(boundResources);\r
- if(temp>bestValue) {\r
- bestValue = temp;\r
- bestConstraint = constraint;\r
- }\r
- return true;\r
- }\r
- \r
- });\r
- }\r
- \r
- private void applyConstraint(THashSet<Resource> resources, IConstraint constraint) {\r
- THashSet<Resource> unbounded = new THashSet<Resource>();\r
- for(Resource r : constraint.binds())\r
- if(resources.remove(r)) {\r
- unbounded.add(r);\r
- boundResources.put(r, id++);\r
- } \r
- Instruction temp = constraint.createQueryInstruction(boundResources, unbounded);\r
- cur.next = temp;\r
- cur = temp; \r
- }\r
- \r
- private void applyConstraints(THashSet<Resource> resources, THashSet<IConstraint> constraints) {\r
- while(!constraints.isEmpty()) {\r
- findBestConstraint(constraints); \r
- if(bestConstraint != null) {\r
- applyConstraint(resources, bestConstraint);\r
- constraints.remove(bestConstraint);\r
- }\r
- else\r
- throw new RuntimeException("Cannot form a directed mapping.");\r
- }\r
- }\r
- \r
- public void orderSourceConstraints() {\r
- applyConstraints(sourceResources, sourceConstraints);\r
- if(!sourceResources.isEmpty())\r
- throw new RuntimeException("Couldn't bind all source resources");\r
- }\r
- \r
- public void orderTargetConstraints() {\r
- THashSet<ConstraintGroup> groups = new THashSet<ConstraintGroup>(constraintGroups);\r
- while(!groups.isEmpty()) {\r
- \r
- // Find a suitable group\r
- \r
- final Ref<ConstraintGroup> possibleGroup = new Ref<ConstraintGroup>();\r
- final Collection<ConstraintGroup> removableGroups = new ArrayList<ConstraintGroup>();\r
- groups.forEach(new TObjectProcedure<ConstraintGroup>() {\r
-\r
- @Override\r
- public boolean execute(ConstraintGroup group) {\r
- for(Resource target : group.targets)\r
- if(boundResources.containsKey(target)) {\r
- removableGroups.add(group);\r
- return true;\r
- }\r
- for(Resource dep : group.dependencies)\r
- if(!boundResources.containsKey(dep))\r
- return true;\r
- possibleGroup.value = group;\r
- return false;\r
- }\r
- \r
- });\r
- groups.removeAll(removableGroups);\r
- if(possibleGroup.value == null) {\r
- if(!groups.isEmpty())\r
- throw new RuntimeException("Couldn't find a suitable group.");\r
- break;\r
- }\r
- groups.remove(possibleGroup.value);\r
- ConstraintGroup group = possibleGroup.value;\r
- \r
- // Order group constraints\r
- \r
- THashSet<IConstraint> groupConstraints = new THashSet<IConstraint>();\r
- for(IConstraint constraint : group.constraints)\r
- if(targetConstraints.remove(constraint))\r
- groupConstraints.add(constraint);\r
- \r
- applyConstraints(targetResources, groupConstraints);\r
- \r
- // Apply other constraints\r
- \r
- final Collection<IConstraint> removableConstraints = new ArrayList<IConstraint>();\r
- targetConstraints.forEach(new TObjectProcedure<IConstraint>() {\r
-\r
- @Override\r
- public boolean execute(IConstraint constraint) {\r
- for(Resource r : constraint.binds())\r
- if(!boundResources.containsKey(r))\r
- return true;\r
- \r
- Instruction temp = constraint.createQueryInstruction(boundResources, EMPTY_SET);\r
- cur.next = temp;\r
- cur = temp;\r
- \r
- removableConstraints.add(constraint);\r
- return true;\r
- }\r
- \r
- });\r
- targetConstraints.removeAll(removableConstraints);\r
- }\r
- if(!targetResources.isEmpty())\r
- throw new RuntimeException("Couldn't bind all target resources");\r
- }\r
- \r
- }\r
- */\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.mapping.pattern;
+
+
+public class MappingRule {
+ /*
+ static final THashSet<Resource> EMPTY_SET = new THashSet<Resource>();
+
+ THashMap<Resource, Resource> resourcesByDomains = new THashMap<Resource, Resource>();
+ Collection<IConstraint> constraints = new ArrayList<IConstraint>();
+ Collection<ConstraintGroup> constraintGroups = new ArrayList<ConstraintGroup>();
+
+ static class ConstraintGroup {
+ Collection<IConstraint> constraints;
+ Collection<Resource> targets;
+ Collection<Resource> dependencies;
+ }
+
+ class DirectedRuleBuilder {
+ THashSet<Resource> sourceResources = new THashSet<Resource>();
+ THashSet<Resource> targetResources = new THashSet<Resource>();
+ THashSet<IConstraint> sourceConstraints = new THashSet<IConstraint>();
+ THashSet<IConstraint> targetConstraints = new THashSet<IConstraint>();
+ TObjectIntHashMap<Resource> boundResources;
+ int id;
+
+ Instruction root = new DummyInstruction();
+ Instruction cur = root;
+
+ public DirectedRuleBuilder(final THashSet<Resource> sourceDomains,
+ TObjectIntHashMap<Resource> boundResources, int id) {
+ this.boundResources = boundResources;
+ this.id = id;
+
+ // Classify resources
+
+ resourcesByDomains.forEachEntry(new TObjectObjectProcedure<Resource, Resource>() {
+
+ @Override
+ public boolean execute(Resource domain, Resource resource) {
+ if(sourceDomains.contains(domain))
+ sourceResources.add(resource);
+ else
+ targetResources.add(resource);
+ return true;
+ }
+
+ });
+
+ // Classify constraints
+
+ for(IConstraint constraint : constraints) {
+ if(sourceResources.containsAll(constraint.binds()))
+ sourceConstraints.add(constraint);
+ else
+ targetConstraints.add(constraint);
+ }
+ }
+
+ int bestValue;
+ IConstraint bestConstraint;
+
+ private void findBestConstraint(THashSet<IConstraint> constraints) {
+ bestValue = 0;
+ bestConstraint = null;
+ sourceConstraints.forEach(new TObjectProcedure<IConstraint>() {
+
+ @Override
+ public boolean execute(IConstraint constraint) {
+ int temp = constraint.isApplicable(boundResources);
+ if(temp>bestValue) {
+ bestValue = temp;
+ bestConstraint = constraint;
+ }
+ return true;
+ }
+
+ });
+ }
+
+ private void applyConstraint(THashSet<Resource> resources, IConstraint constraint) {
+ THashSet<Resource> unbounded = new THashSet<Resource>();
+ for(Resource r : constraint.binds())
+ if(resources.remove(r)) {
+ unbounded.add(r);
+ boundResources.put(r, id++);
+ }
+ Instruction temp = constraint.createQueryInstruction(boundResources, unbounded);
+ cur.next = temp;
+ cur = temp;
+ }
+
+ private void applyConstraints(THashSet<Resource> resources, THashSet<IConstraint> constraints) {
+ while(!constraints.isEmpty()) {
+ findBestConstraint(constraints);
+ if(bestConstraint != null) {
+ applyConstraint(resources, bestConstraint);
+ constraints.remove(bestConstraint);
+ }
+ else
+ throw new RuntimeException("Cannot form a directed mapping.");
+ }
+ }
+
+ public void orderSourceConstraints() {
+ applyConstraints(sourceResources, sourceConstraints);
+ if(!sourceResources.isEmpty())
+ throw new RuntimeException("Couldn't bind all source resources");
+ }
+
+ public void orderTargetConstraints() {
+ THashSet<ConstraintGroup> groups = new THashSet<ConstraintGroup>(constraintGroups);
+ while(!groups.isEmpty()) {
+
+ // Find a suitable group
+
+ final Ref<ConstraintGroup> possibleGroup = new Ref<ConstraintGroup>();
+ final Collection<ConstraintGroup> removableGroups = new ArrayList<ConstraintGroup>();
+ groups.forEach(new TObjectProcedure<ConstraintGroup>() {
+
+ @Override
+ public boolean execute(ConstraintGroup group) {
+ for(Resource target : group.targets)
+ if(boundResources.containsKey(target)) {
+ removableGroups.add(group);
+ return true;
+ }
+ for(Resource dep : group.dependencies)
+ if(!boundResources.containsKey(dep))
+ return true;
+ possibleGroup.value = group;
+ return false;
+ }
+
+ });
+ groups.removeAll(removableGroups);
+ if(possibleGroup.value == null) {
+ if(!groups.isEmpty())
+ throw new RuntimeException("Couldn't find a suitable group.");
+ break;
+ }
+ groups.remove(possibleGroup.value);
+ ConstraintGroup group = possibleGroup.value;
+
+ // Order group constraints
+
+ THashSet<IConstraint> groupConstraints = new THashSet<IConstraint>();
+ for(IConstraint constraint : group.constraints)
+ if(targetConstraints.remove(constraint))
+ groupConstraints.add(constraint);
+
+ applyConstraints(targetResources, groupConstraints);
+
+ // Apply other constraints
+
+ final Collection<IConstraint> removableConstraints = new ArrayList<IConstraint>();
+ targetConstraints.forEach(new TObjectProcedure<IConstraint>() {
+
+ @Override
+ public boolean execute(IConstraint constraint) {
+ for(Resource r : constraint.binds())
+ if(!boundResources.containsKey(r))
+ return true;
+
+ Instruction temp = constraint.createQueryInstruction(boundResources, EMPTY_SET);
+ cur.next = temp;
+ cur = temp;
+
+ removableConstraints.add(constraint);
+ return true;
+ }
+
+ });
+ targetConstraints.removeAll(removableConstraints);
+ }
+ if(!targetResources.isEmpty())
+ throw new RuntimeException("Couldn't bind all target resources");
+ }
+
+ }
+ */
+}