forked from jgraph/mxgraph
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmxMultiplicity.java
More file actions
244 lines (209 loc) · 5.75 KB
/
mxMultiplicity.java
File metadata and controls
244 lines (209 loc) · 5.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
package com.mxgraph.view;
import java.util.Collection;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.w3c.dom.Element;
import com.mxgraph.model.mxIGraphModel;
import com.mxgraph.util.mxUtils;
public class mxMultiplicity
{
private static final Logger log = Logger.getLogger(mxMultiplicity.class.getName());
/**
* Defines the type of the source or target terminal. The type is a string
* passed to mxUtils.isNode together with the source or target vertex
* value as the first argument.
*/
protected String type;
/**
* Optional string that specifies the attributename to be passed to
* mxCell.is to check if the rule applies to a cell.
*/
protected String attr;
/**
* Optional string that specifies the value of the attribute to be passed
* to mxCell.is to check if the rule applies to a cell.
*/
protected String value;
/**
* Boolean that specifies if the rule is applied to the source or target
* terminal of an edge.
*/
protected boolean source;
/**
* Defines the minimum number of connections for which this rule applies.
* Default is 0.
*/
protected int min = 0;
/**
* Defines the maximum number of connections for which this rule applies.
* A value of 'n' means unlimited times. Default is 'n'.
*/
protected String max = "n";
/**
* Holds an array of strings that specify the type of neighbor for which
* this rule applies. The strings are used in mxCell.is on the opposite
* terminal to check if the rule applies to the connection.
*/
protected Collection<String> validNeighbors;
/**
* Boolean indicating if the list of validNeighbors are those that are allowed
* for this rule or those that are not allowed for this rule.
*/
protected boolean validNeighborsAllowed = true;
/**
* Holds the localized error message to be displayed if the number of
* connections for which the rule applies is smaller than min or greater
* than max.
*/
protected String countError;
/**
* Holds the localized error message to be displayed if the type of the
* neighbor for a connection does not match the rule.
*/
protected String typeError;
/**
*
*/
public mxMultiplicity(boolean source, String type, String attr,
String value, int min, String max,
Collection<String> validNeighbors, String countError,
String typeError, boolean validNeighborsAllowed)
{
this.source = source;
this.type = type;
this.attr = attr;
this.value = value;
this.min = min;
this.max = max;
this.validNeighbors = validNeighbors;
this.countError = countError;
this.typeError = typeError;
this.validNeighborsAllowed = validNeighborsAllowed;
}
/**
* Function: check
*
* Checks the multiplicity for the given arguments and returns the error
* for the given connection or null if the multiplicity does not apply.
*
* Parameters:
*
* graph - Reference to the enclosing graph instance.
* edge - Cell that represents the edge to validate.
* source - Cell that represents the source terminal.
* target - Cell that represents the target terminal.
* sourceOut - Number of outgoing edges from the source terminal.
* targetIn - Number of incoming edges for the target terminal.
*/
public String check(mxGraph graph, Object edge, Object source,
Object target, int sourceOut, int targetIn)
{
StringBuffer error = new StringBuffer();
if ((this.source && checkTerminal(graph, source, edge))
|| (!this.source && checkTerminal(graph, target, edge)))
{
if (!isUnlimited())
{
int m = getMaxValue();
if (m == 0 || (this.source && sourceOut >= m)
|| (!this.source && targetIn >= m))
{
error.append(countError + "\n");
}
}
if (validNeighbors != null && typeError != null && validNeighbors.size() > 0)
{
boolean isValid = checkNeighbors(graph, edge, source, target);
if (!isValid)
{
error.append(typeError + "\n");
}
}
}
return (error.length() > 0) ? error.toString() : null;
}
/**
* Checks the type of the given value.
*/
public boolean checkNeighbors(mxGraph graph, Object edge, Object source,
Object target)
{
mxIGraphModel model = graph.getModel();
Object sourceValue = model.getValue(source);
Object targetValue = model.getValue(target);
boolean isValid = !validNeighborsAllowed;
Iterator<String> it = validNeighbors.iterator();
while (it.hasNext())
{
String tmp = it.next();
if (this.source && checkType(graph, targetValue, tmp))
{
isValid = validNeighborsAllowed;
break;
}
else if (!this.source && checkType(graph, sourceValue, tmp))
{
isValid = validNeighborsAllowed;
break;
}
}
return isValid;
}
/**
* Checks the type of the given value.
*/
public boolean checkTerminal(mxGraph graph, Object terminal, Object edge)
{
Object userObject = graph.getModel().getValue(terminal);
return checkType(graph, userObject, type, attr, value);
}
/**
* Checks the type of the given value.
*/
public boolean checkType(mxGraph graph, Object value, String type)
{
return checkType(graph, value, type, null, null);
}
/**
* Checks the type of the given value.
*/
public boolean checkType(mxGraph graph, Object value, String type,
String attr, String attrValue)
{
if (value != null)
{
if (value instanceof Element)
{
return mxUtils.isNode(value, type, attr, attrValue);
}
else
{
return value.equals(type);
}
}
return false;
}
/**
* Returns true if max is "n" (unlimited).
*/
public boolean isUnlimited()
{
return max == null || max == "n";
}
/**
* Returns the numeric value of max.
*/
public int getMaxValue()
{
try
{
return Integer.parseInt(max);
}
catch (NumberFormatException e)
{
log.log(Level.SEVERE, "Failed to parse max value " + max, e);
}
return 0;
}
}