Source Code Cross Referenced for Mode.java in  » XML » saxonb » net » sf » saxon » trans » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » XML » saxonb » net.sf.saxon.trans 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package net.sf.saxon.trans;
002:
003:        import net.sf.saxon.Configuration;
004:        import net.sf.saxon.functions.NormalizeSpace;
005:        import net.sf.saxon.expr.XPathContext;
006:        import net.sf.saxon.expr.XPathContextMajor;
007:        import net.sf.saxon.om.Navigator;
008:        import net.sf.saxon.om.NodeInfo;
009:        import net.sf.saxon.pattern.NoNodeTest;
010:        import net.sf.saxon.pattern.Pattern;
011:        import net.sf.saxon.type.Type;
012:
013:        import java.io.Serializable;
014:
015:        /**
016:         * A Mode is a collection of rules; the selection of a rule to apply to a given element
017:         * is determined by a Pattern.
018:         *
019:         * @author Michael H. Kay
020:         */
021:
022:        public class Mode implements  Serializable {
023:
024:            public static final int DEFAULT_MODE = -1;
025:            public static final int ALL_MODES = -2;
026:            public static final int NAMED_MODE = -3;
027:            public static final int STRIPPER_MODE = -4;
028:
029:            private Rule[] ruleDict = new Rule[101 + Type.MAX_NODE_TYPE];
030:            private int sequence = 0; // sequence number for the rules in this Mode
031:            private boolean isDefault;
032:            private boolean isStripper;
033:
034:            /**
035:             * Default constructor - creates a Mode containing no rules
036:             * @param usage one of {@link #DEFAULT_MODE}, {@link #NAMED_MODE}, {@link #STRIPPER_MODE}
037:             */
038:
039:            public Mode(int usage) {
040:                this .isDefault = (usage == DEFAULT_MODE);
041:                this .isStripper = (usage == STRIPPER_MODE);
042:            }
043:
044:            /**
045:             * Construct a new Mode, copying the contents of an existing Mode
046:             *
047:             * @param omniMode the existing mode. May be null, in which case it is not copied
048:             */
049:
050:            public Mode(Mode omniMode) {
051:                isDefault = false;
052:                isStripper = false;
053:                if (omniMode != null) {
054:                    for (int i = 0; i < this .ruleDict.length; i++) {
055:                        if (omniMode.ruleDict[i] != null) {
056:                            this .ruleDict[i] = new Rule(omniMode.ruleDict[i]);
057:                        }
058:                    }
059:                    this .sequence = omniMode.sequence;
060:                }
061:            }
062:
063:            /**
064:             * Determine if this is the default mode
065:             */
066:
067:            public boolean isDefaultMode() {
068:                return isDefault;
069:            }
070:
071:            /**
072:             * Add a rule to the Mode. <br>
073:             * The rule effectively replaces any other rule for the same pattern/mode at the same or a lower
074:             * priority.
075:             *
076:             * @param p          a Pattern
077:             * @param obj        the Object to return from getRule() when the supplied node matches this Pattern
078:             * @param precedence the import precedence of the rule
079:             * @param priority   the explicit or implicit priority of the rule
080:             */
081:
082:            public void addRule(Pattern p, Object obj, int precedence,
083:                    double priority) {
084:
085:                // System.err.println("Add rule, pattern = " + p.toString() + " class " + p.getClass() + ", priority=" + priority);
086:
087:                // Ignore a pattern that will never match, e.g. "@comment"
088:
089:                if (p.getNodeTest() instanceof  NoNodeTest) {
090:                    return;
091:                }
092:
093:                // for fast lookup, we maintain one list for each element name for patterns that can only
094:                // match elements of a given name, one list for each node type for patterns that can only
095:                // match one kind of non-element node, and one generic list.
096:                // Each list is sorted in precedence/priority order so we find the highest-priority rule first
097:
098:                int fingerprint = p.getFingerprint();
099:                int type = p.getNodeKind();
100:
101:                int key = getList(fingerprint, type);
102:                // System.err.println("Fingerprint " + fingerprint + " key " + key + " type " + type);
103:
104:                Rule newRule = new Rule(p, obj, precedence, priority,
105:                        sequence++);
106:
107:                Rule rule = ruleDict[key];
108:                if (rule == null) {
109:                    ruleDict[key] = newRule;
110:                    return;
111:                }
112:
113:                // insert the new rule into this list before others of the same precedence/priority
114:
115:                Rule prev = null;
116:                while (rule != null) {
117:                    if ((rule.precedence < precedence)
118:                            || (rule.precedence == precedence && rule.priority <= priority)) {
119:                        newRule.next = rule;
120:                        if (prev == null) {
121:                            ruleDict[key] = newRule;
122:                        } else {
123:                            prev.next = newRule;
124:                        }
125:                        break;
126:                    } else {
127:                        prev = rule;
128:                        rule = rule.next;
129:                    }
130:                }
131:                if (rule == null) {
132:                    prev.next = newRule;
133:                    newRule.next = null;
134:                }
135:            }
136:
137:            /**
138:             * Determine which list to use for a given pattern (we must also search the generic list)
139:             */
140:
141:            public int getList(int fingerprint, int type) {
142:
143:                if (type == Type.ELEMENT) {
144:                    if (fingerprint == -1) {
145:                        return Type.NODE; // the generic list
146:                    } else {
147:                        return Type.MAX_NODE_TYPE + (fingerprint % 101);
148:                    }
149:                } else {
150:                    return type;
151:                }
152:            }
153:
154:            /**
155:             * Get the rule corresponding to a given Node, by finding the best Pattern match.
156:             *
157:             * @param node the NodeInfo referring to the node to be matched
158:             * @return the object (e.g. a NodeHandler) registered for that element, if any (otherwise null).
159:             */
160:
161:            public Object getRule(NodeInfo node, XPathContext context)
162:                    throws XPathException {
163:                int fingerprint = node.getFingerprint();
164:                // This is inefficient with wrapped object models (DOM, XOM, JDOM),
165:                // but there's not much we can do about it
166:                int type = node.getNodeKind();
167:                int key = getList(fingerprint, type);
168:                int policy = context.getController().getRecoveryPolicy();
169:
170:                // If there are match patterns in the stylesheet that use local variables, we need to allocate
171:                // a new stack frame for evaluating the match patterns. We base this on the match pattern with
172:                // the highest number of range variables, so we can reuse the same stack frame for all rules
173:                // that we test against. If no patterns use range variables, we don't bother allocating a new
174:                // stack frame.
175:
176:                context = perhapsMakeNewContext(context);
177:
178:                Rule specificRule = null;
179:                Rule generalRule = null;
180:                int specificPrecedence = -1;
181:                double specificPriority = Double.NEGATIVE_INFINITY;
182:
183:                // search the specific list for this node type / node name
184:
185:                if (key != Type.NODE) {
186:                    Rule r = ruleDict[key];
187:                    while (r != null) {
188:                        // if we already have a match, and the precedence or priority of this
189:                        // rule is lower, quit the search for a second match
190:                        if (specificRule != null) {
191:                            if (r.precedence < specificPrecedence
192:                                    || (r.precedence == specificPrecedence && r.priority < specificPriority)) {
193:                                break;
194:                            }
195:                        }
196:                        if (r.pattern.matches(node, context)) {
197:
198:                            // is this a second match?
199:                            if (specificRule != null) {
200:                                if (r.precedence == specificPrecedence
201:                                        && r.priority == specificPriority) {
202:                                    reportAmbiguity(node, specificRule, r,
203:                                            context);
204:                                }
205:                                break;
206:                            }
207:                            specificRule = r;
208:                            specificPrecedence = r.precedence;
209:                            specificPriority = r.priority;
210:                            if (policy == Configuration.RECOVER_SILENTLY) {
211:                                break; // find the first; they are in priority order
212:                            }
213:                        }
214:                        r = r.next;
215:                    }
216:                }
217:
218:                // search the general list
219:
220:                Rule r2 = ruleDict[Type.NODE];
221:                while (r2 != null) {
222:                    if (r2.precedence < specificPrecedence
223:                            || (r2.precedence == specificPrecedence && r2.priority < specificPriority)) {
224:                        break; // no point in looking at a lower priority rule than the one we've got
225:                    }
226:                    if (r2.pattern.matches(node, context)) {
227:                        // is it a second match?
228:                        if (generalRule != null) {
229:                            if (r2.precedence == generalRule.precedence
230:                                    && r2.priority == generalRule.priority) {
231:                                reportAmbiguity(node, r2, generalRule, context);
232:                            }
233:                            break;
234:                        } else {
235:                            generalRule = r2;
236:                            if (policy == Configuration.RECOVER_SILENTLY) {
237:                                break; // find only the first; they are in priority order
238:                            }
239:                        }
240:                    }
241:                    r2 = r2.next;
242:                }
243:
244:                if (specificRule != null && generalRule == null) {
245:                    return specificRule.object;
246:                }
247:                if (specificRule == null && generalRule != null) {
248:                    return generalRule.object;
249:                }
250:                if (specificRule != null && generalRule != null) {
251:                    if (specificRule.precedence == generalRule.precedence
252:                            && specificRule.priority == generalRule.priority) {
253:                        // This situation is exceptional: we have a "specific" pattern and
254:                        // a "general" pattern with the same priority. We have to select
255:                        // the one that was added last
256:                        // (Bug reported by Norman Walsh Jan 2002)
257:                        Object result = (specificRule.sequence > generalRule.sequence ? specificRule.object
258:                                : generalRule.object);
259:
260:                        if (policy != Configuration.RECOVER_SILENTLY) {
261:                            reportAmbiguity(node, specificRule, generalRule,
262:                                    context);
263:                        }
264:                        return result;
265:                    }
266:                    if (specificRule.precedence > generalRule.precedence
267:                            || (specificRule.precedence == generalRule.precedence && specificRule.priority >= generalRule.priority)) {
268:                        return specificRule.object;
269:                    } else {
270:                        return generalRule.object;
271:                    }
272:                }
273:                return null;
274:            }
275:
276:            /**
277:             * Make a new XPath context for evaluating patterns if there is any possibility that the
278:             * pattern uses local variables
279:             *
280:             * @param context The existing XPath context
281:             * @return a new XPath context (or the existing context if no new context was created)
282:             */
283:
284:            private XPathContext perhapsMakeNewContext(XPathContext context) {
285:                int patternLocals = context.getController().getExecutable()
286:                        .getLargestPatternStackFrame();
287:                if (patternLocals > 0) {
288:                    context = context.newContext();
289:                    context.setOrigin(context.getController());
290:                    ((XPathContextMajor) context).openStackFrame(patternLocals);
291:                }
292:                return context;
293:            }
294:
295:            /**
296:             * Get the rule corresponding to a given Node, by finding the best Pattern match, subject to a minimum
297:             * and maximum precedence. (This supports xsl:apply-imports)
298:             *
299:             * @param node the NodeInfo referring to the node to be matched
300:             * @return the object (e.g. a NodeHandler) registered for that element, if any (otherwise null).
301:             */
302:
303:            public Object getRule(NodeInfo node, int min, int max,
304:                    XPathContext context) throws XPathException {
305:                int fing = node.getFingerprint();
306:                int type = node.getNodeKind();
307:                int key = getList(fing, type);
308:
309:                Rule specificRule = null;
310:                Rule generalRule = null;
311:
312:                context = perhapsMakeNewContext(context);
313:
314:                // search the the specific list for this node type / name
315:
316:                if (key != Type.NODE) {
317:                    Rule r = ruleDict[key];
318:                    while (r != null) {
319:                        if (r.precedence >= min && r.precedence <= max
320:                                && r.pattern.matches(node, context)) {
321:                            specificRule = r;
322:                            break; // find the first; they are in priority order
323:                        }
324:                        r = r.next;
325:                    }
326:                }
327:
328:                // search the generic list
329:
330:                Rule r2 = ruleDict[Type.NODE];
331:                while (r2 != null) {
332:                    if (r2.precedence >= min && r2.precedence <= max
333:                            && r2.pattern.matches(node, context)) {
334:                        generalRule = r2;
335:                        break; // find only the first; they are in priority order
336:                    }
337:                    r2 = r2.next;
338:                }
339:                if (specificRule != null && generalRule == null) {
340:                    return specificRule.object;
341:                }
342:                if (specificRule == null && generalRule != null) {
343:                    return generalRule.object;
344:                }
345:                if (specificRule != null && generalRule != null) {
346:                    if (specificRule.precedence > generalRule.precedence
347:                            || (specificRule.precedence == generalRule.precedence && specificRule.priority >= generalRule.priority)) {
348:                        return specificRule.object;
349:                    } else {
350:                        return generalRule.object;
351:                    }
352:                }
353:                return null;
354:            }
355:
356:            /**
357:             * Get the rule corresponding to a given Node, by finding the next-best Pattern match
358:             * after the specified object.
359:             *
360:             * @param node the NodeInfo referring to the node to be matched
361:             * @return the object (e.g. a NodeHandler) registered for that element, if any (otherwise null).
362:             */
363:
364:            public Object getNextMatchRule(NodeInfo node,
365:                    Object currentHandler, XPathContext context)
366:                    throws XPathException {
367:                int fingerprint = node.getFingerprint();
368:                int type = node.getNodeKind();
369:                int key = getList(fingerprint, type);
370:                int policy = context.getController().getRecoveryPolicy();
371:
372:                int currentPrecedence = -1;
373:                double currentPriority = -1.0;
374:                int currentSequence = -1;
375:
376:                context = perhapsMakeNewContext(context);
377:
378:                // First find the Rule object corresponding to the current handler
379:
380:                Rule r = ruleDict[key];
381:                while (r != null) {
382:                    if (r.object == currentHandler) {
383:                        currentPrecedence = r.precedence;
384:                        currentPriority = r.priority;
385:                        currentSequence = r.sequence;
386:                        break;
387:                    } else {
388:                        r = r.next;
389:                    }
390:                }
391:                if (r == null) {
392:                    r = ruleDict[Type.NODE];
393:                    while (r != null) {
394:                        if (r.object == currentHandler) {
395:                            currentPrecedence = r.precedence;
396:                            currentPriority = r.priority;
397:                            currentSequence = r.sequence;
398:                            break;
399:                        } else {
400:                            r = r.next;
401:                        }
402:                    }
403:                    if (r == null) {
404:                        DynamicError de = new DynamicError(
405:                                "Internal error: current template doesn't match current node");
406:                        de.setXPathContext(context);
407:                        de.setErrorCode("SAXON:0000");
408:                        throw de;
409:                    }
410:                }
411:
412:                Rule specificRule = null;
413:                Rule generalRule = null;
414:                int specificPrecedence = -1;
415:                double specificPriority = Double.NEGATIVE_INFINITY;
416:
417:                // search the specific list for this node type / node name
418:
419:                // System.err.println("Hash key = " + key);
420:
421:                if (key != Type.NODE) {
422:                    r = ruleDict[key];
423:                    while (r != null) {
424:                        // skip this rule if its template is the current template. (There can be more than
425:                        // one rule for the same template in the case of a union pattern.)
426:                        if (r.object == currentHandler) {
427:                            // skip this rule
428:                        } else
429:                        // skip this rule unless it's "below" the current rule in search order
430:                        if ((r.precedence > currentPrecedence)
431:                                || (r.precedence == currentPrecedence && (r.priority > currentPriority || (r.priority == currentPriority && r.sequence >= currentSequence)))) {
432:                            // skip this rule
433:                        } else {
434:                            // quit the search on finding the second (recoverable error) match
435:                            if (specificRule != null) {
436:                                if (r.precedence < specificPrecedence
437:                                        || (r.precedence == specificPrecedence && r.priority < specificPriority)) {
438:                                    break;
439:                                }
440:                            }
441:                            //System.err.println("Testing " + Navigator.getPath(node) + " against " + r.pattern);
442:                            if (r.pattern.matches(node, context)) {
443:                                //System.err.println("Matches");
444:
445:                                // is this a second match?
446:                                if (specificRule != null) {
447:                                    if (r.precedence == specificPrecedence
448:                                            && r.priority == specificPriority) {
449:                                        reportAmbiguity(node, specificRule, r,
450:                                                context);
451:                                    }
452:                                    break;
453:                                }
454:                                specificRule = r;
455:                                specificPrecedence = r.precedence;
456:                                specificPriority = r.priority;
457:                                if (policy == Configuration.RECOVER_SILENTLY) {
458:                                    break; // find the first; they are in priority order
459:                                }
460:                            }
461:                        }
462:                        r = r.next;
463:                    }
464:                }
465:
466:                // search the general list
467:
468:                Rule r2 = ruleDict[Type.NODE];
469:                while (r2 != null) {
470:                    // skip this rule if the template is the current template
471:                    if (r2.object == currentHandler) {
472:                        // skip this rule
473:                    } else
474:                    // skip this rule unless it's "after" the current rule in search order
475:                    if ((r2.precedence > currentPrecedence)
476:                            || (r2.precedence == currentPrecedence && (r2.priority > currentPriority || (r2.priority == currentPriority && r2.sequence >= currentSequence)))) {
477:                        // skip this rule
478:                    } else {
479:                        if (r2.precedence < specificPrecedence
480:                                || (r2.precedence == specificPrecedence && r2.priority < specificPriority)) {
481:                            break; // no point in looking at a lower priority rule than the one we've got
482:                        }
483:                        if (r2.pattern.matches(node, context)) {
484:                            // is it a second match?
485:                            if (generalRule != null) {
486:                                if (r2.precedence == generalRule.precedence
487:                                        && r2.priority == generalRule.priority) {
488:                                    reportAmbiguity(node, r2, generalRule,
489:                                            context);
490:                                }
491:                                break;
492:                            } else {
493:                                generalRule = r2;
494:                                if (policy == Configuration.RECOVER_SILENTLY) {
495:                                    break; // find only the first; they are in priority order
496:                                }
497:                            }
498:                        }
499:                    }
500:                    r2 = r2.next;
501:                }
502:
503:                if (specificRule != null && generalRule == null) {
504:                    return specificRule.object;
505:                }
506:                if (specificRule == null && generalRule != null) {
507:                    return generalRule.object;
508:                }
509:                if (specificRule != null && generalRule != null) {
510:                    if (specificRule.precedence == generalRule.precedence
511:                            && specificRule.priority == generalRule.priority) {
512:                        // This situation is exceptional: we have a "specific" pattern and
513:                        // a "general" pattern with the same priority. We have to select
514:                        // the one that was added last
515:                        // (Bug reported by Norman Walsh Jan 2002)
516:                        Object result = (specificRule.sequence > generalRule.sequence ? specificRule.object
517:                                : generalRule.object);
518:
519:                        if (policy != Configuration.RECOVER_SILENTLY) {
520:                            reportAmbiguity(node, specificRule, generalRule,
521:                                    context);
522:                        }
523:                        return result;
524:                    }
525:                    if (specificRule.precedence > generalRule.precedence
526:                            || (specificRule.precedence == generalRule.precedence && specificRule.priority >= generalRule.priority)) {
527:                        return specificRule.object;
528:                    } else {
529:                        return generalRule.object;
530:                    }
531:                }
532:                return null;
533:            }
534:
535:            /**
536:             * Report an ambiguity, that is, the situation where two rules of the same
537:             * precedence and priority match the same node
538:             *
539:             * @param node The node that matches two or more rules
540:             * @param r1   The first rule that the node matches
541:             * @param r2   The second rule that the node matches
542:             * @param c    The controller for the transformation
543:             */
544:
545:            private void reportAmbiguity(NodeInfo node, Rule r1, Rule r2,
546:                    XPathContext c) throws XPathException {
547:                // don't report an error if the conflict is between two branches of the same
548:                // Union pattern
549:                if (r1.object == r2.object) {
550:                    return;
551:                }
552:                String path;
553:                String errorCode = "XTRE0540";
554:
555:                if (isStripper) {
556:                    // don't report an error if the conflict is between strip-space and strip-space, or
557:                    // preserve-space and preserve-space
558:                    if (r1.object.equals(r2.object)) {
559:                        return;
560:                    }
561:                    errorCode = "XTRE0270";
562:                    path = "xsl:strip-space";
563:                } else {
564:                    path = Navigator.getPath(node);
565:                }
566:
567:                Pattern pat1 = r1.pattern;
568:                Pattern pat2 = r2.pattern;
569:
570:                DynamicError err = new DynamicError("Ambiguous rule match for "
571:                        + path + '\n' + "Matches both \"" + showPattern(pat1)
572:                        + "\" on line " + pat1.getLineNumber() + " of "
573:                        + pat1.getSystemId() + "\nand \"" + showPattern(pat2)
574:                        + "\" on line " + pat2.getLineNumber() + " of "
575:                        + pat2.getSystemId());
576:                err.setErrorCode(errorCode);
577:                err.setLocator(c.getOrigin().getInstructionInfo());
578:                c.getController().recoverableError(err);
579:            }
580:
581:            private static String showPattern(Pattern p) {
582:                // Complex patterns can be laid out with lots of whitespace, which looks messy in the error message
583:                return NormalizeSpace.normalize(p.toString()).toString();
584:            }
585:
586:            /**
587:             * Inner class Rule used to support the implementation
588:             */
589:
590:            public static class Rule implements  Serializable {
591:                public Pattern pattern;
592:                public Object object;
593:                public int precedence;
594:                public double priority;
595:                public int sequence;
596:                public Rule next;
597:
598:                /**
599:                 * Create a Rule
600:                 *
601:                 * @param p    the pattern that this rule matches
602:                 * @param o    the object invoked by this rule (usually a Template)
603:                 * @param prec the precedence of the rule
604:                 * @param prio the priority of the rule
605:                 * @param seq  a sequence number for ordering of rules
606:                 */
607:
608:                public Rule(Pattern p, Object o, int prec, double prio, int seq) {
609:                    pattern = p;
610:                    object = o;
611:                    precedence = prec;
612:                    priority = prio;
613:                    next = null;
614:                    sequence = seq;
615:                }
616:
617:                /**
618:                 * Copy a rule, including the chain of rules linked to it
619:                 *
620:                 * @param r
621:                 */
622:
623:                public Rule(Rule r) {
624:                    this .pattern = r.pattern;
625:                    this .object = r.object;
626:                    this .precedence = r.precedence;
627:                    this .priority = r.priority;
628:                    this .sequence = r.sequence;
629:                    if (r.next == null) {
630:                        this .next = null;
631:                    } else {
632:                        this .next = new Rule(r.next);
633:                    }
634:                }
635:
636:            }
637:
638:        }
639:
640:        //
641:        // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
642:        // you may not use this file except in compliance with the License. You may obtain a copy of the
643:        // License at http://www.mozilla.org/MPL/
644:        //
645:        // Software distributed under the License is distributed on an "AS IS" basis,
646:        // WITHOUT WARRANTY OF ANY KIND, either express or implied.
647:        // See the License for the specific language governing rights and limitations under the License.
648:        //
649:        // The Original Code is: all this file.
650:        //
651:        // The Initial Developer of the Original Code is Michael H. Kay.
652:        //
653:        // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
654:        //
655:        // Contributor(s): none.
656:        //
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.