Mercurial > projects > dwt-addons
comparison dwtx/core/runtime/jobs/MultiRule.d @ 122:9d0585bcb7aa
Add core.jobs package
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Tue, 12 Aug 2008 02:34:21 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
121:c0304616ea23 | 122:9d0585bcb7aa |
---|---|
1 /******************************************************************************* | |
2 * Copyright (c) 2003, 2008 IBM Corporation and others. | |
3 * All rights reserved. This program and the accompanying materials | |
4 * are made available under the terms of the Eclipse Public License v1.0 | |
5 * which accompanies this distribution, and is available at | |
6 * http://www.eclipse.org/legal/epl-v10.html | |
7 * | |
8 * Contributors: | |
9 * IBM - Initial API and implementation | |
10 * Port to the D programming language: | |
11 * Frank Benoit <benoit@tionex.de> | |
12 *******************************************************************************/ | |
13 module dwtx.core.runtime.jobs.MultiRule; | |
14 | |
15 import dwt.dwthelper.utils; | |
16 import dwtx.dwtxhelper.Collection; | |
17 | |
18 import dwtx.core.runtime.jobs.ISchedulingRule; | |
19 | |
20 /** | |
21 * A MultiRule is a compound scheduling rule that represents a fixed group of child | |
22 * scheduling rules. A MultiRule conflicts with another rule if any of its children conflict | |
23 * with that rule. More formally, a compound rule represents a logical intersection | |
24 * of its child rules with respect to the <code>isConflicting</code> equivalence | |
25 * relation. | |
26 * <p> | |
27 * A MultiRule will never contain other MultiRules as children. If a MultiRule is provided | |
28 * as a child, its children will be added instead. | |
29 * </p> | |
30 * | |
31 * @since 3.0 | |
32 * @noextend This class is not intended to be subclassed by clients. | |
33 */ | |
34 public class MultiRule : ISchedulingRule { | |
35 private ISchedulingRule[] rules; | |
36 | |
37 /** | |
38 * Returns a scheduling rule that encompasses all provided rules. The resulting | |
39 * rule may or may not be an instance of <code>MultiRule</code>. If all | |
40 * provided rules are <code>null</code> then the result will be | |
41 * <code>null</code>. | |
42 * | |
43 * @param ruleArray An array of scheduling rules, some of which may be <code>null</code> | |
44 * @return a combined scheduling rule, or <code>null</code> | |
45 * @since 3.1 | |
46 */ | |
47 public static ISchedulingRule combine(ISchedulingRule[] ruleArray) { | |
48 ISchedulingRule result = null; | |
49 for (int i = 0; i < ruleArray.length; i++) { | |
50 if (ruleArray[i] is null) | |
51 continue; | |
52 if (result is null) { | |
53 result = ruleArray[i]; | |
54 continue; | |
55 } | |
56 result = combine(result, ruleArray[i]); | |
57 } | |
58 return result; | |
59 } | |
60 | |
61 /** | |
62 * Returns a scheduling rule that encompasses both provided rules. The resulting | |
63 * rule may or may not be an instance of <code>MultiRule</code>. If both | |
64 * provided rules are <code>null</code> then the result will be | |
65 * <code>null</code>. | |
66 * | |
67 * @param rule1 a scheduling rule, or <code>null</code> | |
68 * @param rule2 another scheduling rule, or <code>null</code> | |
69 * @return a combined scheduling rule, or <code>null</code> | |
70 */ | |
71 public static ISchedulingRule combine(ISchedulingRule rule1, ISchedulingRule rule2) { | |
72 if (rule1 is rule2) | |
73 return rule1; | |
74 if (rule1 is null) | |
75 return rule2; | |
76 if (rule2 is null) | |
77 return rule1; | |
78 if (rule1.contains(rule2)) | |
79 return rule1; | |
80 if (rule2.contains(rule1)) | |
81 return rule2; | |
82 MultiRule result = new MultiRule(); | |
83 result.rules = [rule1, rule2]; | |
84 //make sure we don't end up with nested multi-rules | |
85 if (cast(MultiRule)rule1 || cast(MultiRule)rule2 ) | |
86 result.rules = flatten(result.rules); | |
87 return result; | |
88 } | |
89 | |
90 /* | |
91 * Collapses an array of rules that may contain MultiRules into an | |
92 * array in which no rules are MultiRules. | |
93 */ | |
94 private static ISchedulingRule[] flatten(ISchedulingRule[] nestedRules) { | |
95 ArrayList myRules = new ArrayList(nestedRules.length); | |
96 for (int i = 0; i < nestedRules.length; i++) { | |
97 if (cast(MultiRule)nestedRules[i] ) { | |
98 ISchedulingRule[] children = (cast(MultiRule) nestedRules[i]).getChildren(); | |
99 for (int j = 0; j < children.length; j++) | |
100 myRules.add(cast(Object)children[j]); | |
101 } else { | |
102 myRules.add(cast(Object)nestedRules[i]); | |
103 } | |
104 } | |
105 return arraycast!(ISchedulingRule)( myRules.toArray() ); | |
106 } | |
107 | |
108 /** | |
109 * Creates a new scheduling rule that composes a set of nested rules. | |
110 * | |
111 * @param nestedRules the nested rules for this compound rule. | |
112 */ | |
113 public this(ISchedulingRule[] nestedRules) { | |
114 this.rules = flatten(nestedRules); | |
115 } | |
116 | |
117 /** | |
118 * Creates a new scheduling rule with no nested rules. For | |
119 * internal use only. | |
120 */ | |
121 private this() { | |
122 //to be invoked only by factory methods | |
123 } | |
124 | |
125 /** | |
126 * Returns the child rules within this rule. | |
127 * @return the child rules | |
128 */ | |
129 public ISchedulingRule[] getChildren() { | |
130 return rules.dup; | |
131 } | |
132 | |
133 /* (non-Javadoc) | |
134 * @see dwtx.core.runtime.jobs.ISchedulingRule#contains(dwtx.core.runtime.jobs.ISchedulingRule) | |
135 */ | |
136 public bool contains(ISchedulingRule rule) { | |
137 if (this is rule) | |
138 return true; | |
139 if (cast(MultiRule)rule ) { | |
140 ISchedulingRule[] otherRules = (cast(MultiRule) rule).getChildren(); | |
141 //for each child of the target, there must be some child in this rule that contains it. | |
142 for (int other = 0; other < otherRules.length; other++) { | |
143 bool found = false; | |
144 for (int mine = 0; !found && mine < rules.length; mine++) | |
145 found = rules[mine].contains(otherRules[other]); | |
146 if (!found) | |
147 return false; | |
148 } | |
149 return true; | |
150 } | |
151 for (int i = 0; i < rules.length; i++) | |
152 if (rules[i].contains(rule)) | |
153 return true; | |
154 return false; | |
155 } | |
156 | |
157 /* (non-Javadoc) | |
158 * @see dwtx.core.runtime.jobs.ISchedulingRule#isConflicting(dwtx.core.runtime.jobs.ISchedulingRule) | |
159 */ | |
160 public bool isConflicting(ISchedulingRule rule) { | |
161 if (this is rule) | |
162 return true; | |
163 if (cast(MultiRule)rule ) { | |
164 ISchedulingRule[] otherRules = (cast(MultiRule) rule).getChildren(); | |
165 for (int j = 0; j < otherRules.length; j++) | |
166 for (int i = 0; i < rules.length; i++) | |
167 if (rules[i].isConflicting(otherRules[j])) | |
168 return true; | |
169 } else { | |
170 for (int i = 0; i < rules.length; i++) | |
171 if (rules[i].isConflicting(rule)) | |
172 return true; | |
173 } | |
174 return false; | |
175 } | |
176 | |
177 /* | |
178 * For debugging purposes only. | |
179 */ | |
180 public String toString() { | |
181 StringBuffer buffer = new StringBuffer(); | |
182 buffer.append("MultiRule["); //$NON-NLS-1$ | |
183 int last = rules.length - 1; | |
184 for (int i = 0; i < rules.length; i++) { | |
185 buffer.append(rules[i] ? (cast(Object)rules[i]).toString() : "null" ); | |
186 if (i !is last) | |
187 buffer.append(','); | |
188 } | |
189 buffer.append(']'); | |
190 return buffer.toString(); | |
191 } | |
192 } |