KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > SOFA > SOFAnet > Repository > ContractRule


1 /*
2  * ContractRule.java
3  *
4  * Created on 3. prosinec 2003, 18:59
5  */

6
7 package SOFA.SOFAnet.Repository;
8
9 import java.io.*;
10 import java.util.*;
11 import java.text.*;
12 import SOFA.Util.XML;
13 import org.w3c.dom.*;
14 import org.xml.sax.SAXException JavaDoc;
15
16 /**
17  * Representation of the one contract rule
18  * (Contract consists of ContractRules - one bussiness contract can cover more
19  * software - ContractRules).
20  * <p>
21  * ContractRule consists of:
22  * <ul>
23  * <li>name of the rule
24  * <li>test description
25  * <li>time validity
26  * <li>software - filter of bundles - whis bundles are covered by this ContractRule
27  * <li>"push part" - whether to push bundles to the nodes and under which conditions
28  * <ul>
29  * <li>filter of "pushing" nodes (contract is taken only if the bundle arrives from such node)
30  * <li>names of destination nodes and number of licence copies to send
31  * <li>counter of pushes - how many times do the push
32  * </ul>
33  * <li>"pull part"
34  * <ul>
35  * <li>filter of nodes that can pull bundles from the node
36  * <li>counter of pulls - how many times can be pulled from this node
37  * </ul>
38  * <li>licence
39  * </ul>
40  * <p>
41  * Contract contains several default settings for all ContractRules (if these thing are not filled in ContractRule).
42  *
43  * @author Ladislav Sobr
44  */

45 public class ContractRule implements Cloneable JavaDoc, Serializable
46 {
47   private Contract parentContract;
48   
49   private String JavaDoc name;
50   private String JavaDoc description;
51   private Date validFrom; //can be null
52
private Date validTo; //can be null
53
private boolean autoDelete;
54   private BundleNameFilter software;
55   private boolean isPush;
56   private int pushCounter; //-1 == no counter
57
private NodeNameLicList pushDestinationNodes;
58   private NodeNameFilter pushNodeFilter;
59   private boolean isPull;
60   private NodeNameFilter pullNodeFilter;
61   private int pullCounter; //-1 == no counter
62
private Licence licence;
63   
64   /** Creates a new instance of ContractRule */
65   public ContractRule(String JavaDoc name, Contract parentContract)
66   {
67     this.name = name;
68     this.parentContract = parentContract;
69     reset();
70   }
71
72   public Object JavaDoc clone()
73   {
74     ContractRule clone = null;
75     try
76     {
77       clone = (ContractRule)super.clone();
78     }
79     catch (CloneNotSupportedException JavaDoc e)
80     {
81       throw new InternalError JavaDoc();
82     }
83     if (software != null) clone.software = (BundleNameFilter)software.clone();
84     if (pushDestinationNodes != null) clone.pushDestinationNodes = (NodeNameLicList)pushDestinationNodes.clone();
85     if (pushNodeFilter != null) clone.pushNodeFilter = (NodeNameFilter)pushNodeFilter.clone();
86     if (pullNodeFilter != null) clone.pullNodeFilter = (NodeNameFilter)pullNodeFilter.clone();
87     return clone;
88   }
89   
90   /**
91    * Resets content of the ContractRule.
92    */

93   protected void reset()
94   {
95     description = "";
96     validFrom = null;
97     validTo = null;
98     autoDelete = false;
99     software = new BundleNameFilter();
100     isPush = false;
101     pushCounter = -1;
102     pushDestinationNodes = null;
103     pushNodeFilter = null;
104     isPull = false;
105     pullNodeFilter = null;
106     pullCounter = -1;
107     licence = new Licence();
108   }
109   
110   /**
111    * Loads the ContractRule from the XML DOM tree.
112    * <p>
113    * XML format:
114    * <p>
115    * <pre>
116    * ?&lt;descripton&gt;string&lt;/description&gt;
117    * ?&lt;validity ?from="date" ?to="date" ?autodelete="boolean"/&gt;
118    *
119    * &lt;software&gt;
120    * BundleNameFilter XML format
121    * &lt;/software&gt;
122    *
123    * ?&lt;push&gt;
124    * ?&lt;push_node_filter&gt; (presence of this tag overrides "defaults" in contract)
125    * NodeNameFilter XML format
126    * &lt;/push_node_filter&gt;
127    * ?&lt;push_destination_nodes&gt; (presence of this tag overrides "defaults" in contract)
128    * NodeNameLicList XML format (presence of "number_of_licences" overrides "number_of_copies" in licence)
129    * &lt;/push_destination_nodes&gt;
130    * ?&lt;counter&gt;integer&lt;/counter&gt;
131    * &lt;/push&gt;
132    *
133    * ?&lt;pull&gt;
134    * ?&lt;pull_node_filter&gt; (presence of this tag overrides "defaults" in contract)
135    * NodeNameFilter XML format
136    * &lt;/pull_node_filter&gt;
137    * ?&lt;counter&gt;integer&lt;/counter&gt;
138    * &lt;/pull&gt;
139    *
140    * &lt;licence&gt;
141    * Licence XML format
142    * &lt;/licence&gt;
143    * </pre>
144    */

145   public void loadFromXML(Element element) throws SAXException JavaDoc
146   {
147     reset();
148     NodeList nl = element.getChildNodes();
149     for (int i = 0; i < nl.getLength(); i++)
150     {
151       Node node = nl.item(i);
152       if (node.getNodeType() == Node.ELEMENT_NODE)
153       {
154         Element el = (Element)node;
155         String JavaDoc nodeName = node.getNodeName();
156         
157         if (nodeName.compareTo("description") == 0)
158         {
159           description = XML.getTextContent(el);
160         }
161         else
162         if (nodeName.compareTo("validity") == 0)
163         {
164           String JavaDoc from = el.getAttribute("from");
165           String JavaDoc to = el.getAttribute("to");
166           String JavaDoc ad = el.getAttribute("autodelete");
167           DateFormat dateFormat = DateFormat.getInstance();
168           if (from.length() > 0)
169           {
170             try
171             {
172               validFrom = dateFormat.parse(from);
173             }
174             catch (ParseException e)
175             {
176               throw new SAXException JavaDoc("Cannot parse date/time format of 'from' attribute of 'validity' tag", e);
177             }
178           }
179           
180           if (to.length() > 0)
181           {
182             try
183             {
184               validTo = dateFormat.parse(to);
185             }
186             catch (ParseException e)
187             {
188               throw new SAXException JavaDoc("Cannot parse date/time format of 'to' attribute of 'validity' tag", e);
189             }
190           }
191
192           if (ad.length() > 0)
193           {
194             ad = ad.trim().toLowerCase();
195             if (ad.compareTo("1") == 0 || ad.compareTo("true") == 0) autoDelete = true;
196           }
197         }
198         else
199         if (nodeName.compareTo("software") == 0)
200         {
201           software.loadFromXML(el);
202         }
203         else
204         if (nodeName.compareTo("push") == 0)
205         {
206           isPush = true;
207           
208           NodeList nl2 = el.getChildNodes();
209           for (int i2 = 0; i2 < nl2.getLength(); i2++)
210           {
211             Node node2 = nl2.item(i2);
212             if (node2.getNodeType() == Node.ELEMENT_NODE)
213             {
214               Element el2 = (Element)node2;
215               String JavaDoc nodeName2 = node2.getNodeName();
216
217               if (nodeName2.compareTo("push_node_filter") == 0)
218               {
219                 pushNodeFilter = new NodeNameFilter();
220                 pushNodeFilter.loadFromXML(el2);
221               }
222               else
223               if (nodeName2.compareTo("push_destination_nodes") == 0)
224               {
225                 pushDestinationNodes = new NodeNameLicList();
226                 pushDestinationNodes.loadFromXML(el2);
227               }
228               else
229               if (nodeName2.compareTo("counter") == 0)
230               {
231                 try
232                 {
233                   int l = Integer.parseInt(XML.getTextContent(el2));
234                   if (l < 0) l = -1;
235                   pushCounter = l;
236                 }
237                 catch (NumberFormatException JavaDoc e)
238                 {
239                   throw new SAXException JavaDoc("Invalid 'integer' format of content of 'counter' tag", e);
240                 }
241               }
242             }
243           }
244         }
245         else
246         if (nodeName.compareTo("pull") == 0)
247         {
248           isPull = true;
249           
250           NodeList nl2 = el.getChildNodes();
251           for (int i2 = 0; i2 < nl2.getLength(); i2++)
252           {
253             Node node2 = nl2.item(i2);
254             if (node2.getNodeType() == Node.ELEMENT_NODE)
255             {
256               Element el2 = (Element)node2;
257               String JavaDoc nodeName2 = node2.getNodeName();
258
259               if (nodeName2.compareTo("pull_node_filter") == 0)
260               {
261                 pullNodeFilter = new NodeNameFilter();
262                 pullNodeFilter.loadFromXML(el2);
263               }
264               else
265               if (nodeName2.compareTo("counter") == 0)
266               {
267                 try
268                 {
269                   int l = Integer.parseInt(XML.getTextContent(el2));
270                   if (l < 0) l = -1;
271                   pullCounter = l;
272                 }
273                 catch (NumberFormatException JavaDoc e)
274                 {
275                   throw new SAXException JavaDoc("Invalid integer format of content of 'counter' tag", e);
276                 }
277               }
278             }
279           }
280         }
281         else
282         if (nodeName.compareTo("licence") == 0)
283         {
284           licence.loadFromXML(el);
285         }
286       }
287     }
288   }
289   
290   /**
291    * Saves the ContractRule to XML DOM tree.
292    */

293   public void saveToXML(Element element)
294   {
295     Document doc = element.getOwnerDocument();
296     Element el;
297   
298     if (description.length() != 0) XML.newTextElement(element, "description", description);
299     
300     if (validFrom != null || validTo != null || autoDelete)
301     {
302       DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
303       el = doc.createElement("validity");
304       if (validFrom != null) el.setAttribute("from", dateFormat.format(validFrom));
305       if (validTo != null) el.setAttribute("to", dateFormat.format(validTo));
306       if (autoDelete) el.setAttribute("autodelete", "true");
307       element.appendChild(el);
308     }
309
310     el = doc.createElement("software");
311     software.saveToXML(el);
312     element.appendChild(el);
313     
314     if (isPush)
315     {
316       el = doc.createElement("push");
317
318       if (pushNodeFilter != null)
319       {
320         Element el2 = doc.createElement("push_node_filter");
321         pushNodeFilter.saveToXML(el2);
322         el.appendChild(el2);
323       }
324       
325       if (pushDestinationNodes != null)
326       {
327         Element el2 = doc.createElement("push_destination_nodes");
328         pushDestinationNodes.saveToXML(el2);
329         el.appendChild(el2);
330       }
331
332       if (pushCounter >= 0)
333       {
334         XML.newTextElement(el, "counter", Integer.toString(pushCounter));
335       }
336
337       element.appendChild(el);
338     }
339
340     if (isPull)
341     {
342       el = doc.createElement("pull");
343
344       if (pullNodeFilter != null)
345       {
346         Element el2 = doc.createElement("pull_node_filter");
347         pullNodeFilter.saveToXML(el2);
348         el.appendChild(el2);
349       }
350
351       if (pullCounter >= 0)
352       {
353         XML.newTextElement(el, "counter", Integer.toString(pullCounter));
354       }
355
356       element.appendChild(el);
357     }
358
359     el = doc.createElement("licence");
360     licence.saveToXML(el);
361     element.appendChild(el);
362   }
363
364   public Contract getParentContract()
365   {
366     return parentContract;
367   }
368   
369   public String JavaDoc getName()
370   {
371     return name;
372   }
373
374   public String JavaDoc getDescription()
375   {
376     return description;
377   }
378   
379   public boolean getAutoDelete()
380   {
381     return autoDelete;
382   }
383   
384   public Date getValidFrom() //can be null
385
{
386     return validFrom;
387   }
388   
389   public Date getValidTo() //can be null
390
{
391     return validTo;
392   }
393   
394   public boolean isValid()
395   {
396     Date now = Calendar.getInstance().getTime();
397     return (validFrom == null || !validFrom.after(now)) && (validTo == null || !validTo.before(now));
398   }
399
400   public boolean toBeDeleted()
401   {
402     return autoDelete && (
403        validTo != null && validTo.before(Calendar.getInstance().getTime()) ||
404        isPush && pushCounter == 0 && (!isPull || pullCounter <= 0) ||
405        isPull && pullCounter == 0 && (!isPush || pushCounter <= 0));
406   }
407   
408   public BundleNameFilter getSoftware()
409   {
410     return software;
411   }
412   
413   public boolean isPush()
414   {
415     return isPush;
416   }
417   
418   public int getPushCounter()
419   {
420     return pushCounter;
421   }
422   
423   public NodeNameLicList getPushDestinationNodes()
424   {
425     return pushDestinationNodes;
426   }
427   
428   public NodeNameFilter getPushNodeFilter()
429   {
430     return pushNodeFilter;
431   }
432   
433   public boolean isPull()
434   {
435     return isPull;
436   }
437   
438   public NodeNameFilter getPullNodeFilter()
439   {
440     return pullNodeFilter;
441   }
442   
443   public int getPullCounter()
444   {
445     return pullCounter;
446   }
447   
448   public Licence getLicence()
449   {
450     return licence;
451   }
452   
453   public void setParentContract(Contract parentContract)
454   {
455     this.parentContract = parentContract;
456   }
457   
458   public void setName(String JavaDoc name)
459   {
460     this.name = name;
461   }
462
463   public void setDescription(String JavaDoc description)
464   {
465     this.description = description;
466   }
467   
468   public void setAutoDelete(boolean autoDelete)
469   {
470     this.autoDelete = autoDelete;
471   }
472   
473   public void setValidFrom(Date validFrom) //can be null
474
{
475     this.validFrom = validFrom;
476   }
477   
478   public void setValidTo(Date validTo) //can be null
479
{
480     this.validTo = validTo;
481   }
482   
483   public void setSoftware(BundleNameFilter software)
484   {
485     this.software = software;
486   }
487   
488   public void setPush(boolean isPush)
489   {
490     this.isPush = isPush;
491   }
492   
493   public void setPushCounter(int pushCounter)
494   {
495     this.pushCounter = pushCounter;
496   }
497   
498   public void decrementPushCounter()
499   {
500     if (pushCounter > 0) pushCounter--;
501   }
502   
503   public void setPushDestinationNodes(NodeNameLicList pushDestinationNodes)
504   {
505     this.pushDestinationNodes = pushDestinationNodes;
506   }
507   
508   public void setPushNodeFilter(NodeNameFilter pushNodeFilter)
509   {
510     this.pushNodeFilter = pushNodeFilter;
511   }
512   
513   public void setPull(boolean isPull)
514   {
515     this.isPull = isPull;
516   }
517   
518   public void setPullNodeFilter(NodeNameFilter pullNodeFilter)
519   {
520     this.pullNodeFilter = pullNodeFilter;
521   }
522
523   public void setPullCounter(int pullCounter)
524   {
525     this.pullCounter = pullCounter;
526   }
527   
528   public void setLicence(Licence licence)
529   {
530     this.licence = licence;
531   }
532   
533   
534   /**
535    * @return true if rule can accept "pull"
536    */

537   public boolean passPull(BundleInfo bundleInfo, NodeInfo nodeInfo, boolean areDefaultsPresent, boolean nodePassedInDefaults)
538   {
539     if (pullNodeFilter == null && areDefaultsPresent && !nodePassedInDefaults) return false;
540     if (!isValid()) return false;
541     if (!isPull) return false;
542     if (!software.pass(bundleInfo)) return false;
543     if (pullNodeFilter != null && !pullNodeFilter.pass(nodeInfo)) return false;
544     if (pullCounter == 0) return false;
545     return true;
546   }
547   
548   /**
549    * Performs "pull" on the rule. Returned Licence can be null,
550    * but only if "pull" cannot be made (passPull would fail).
551    * <p>
552    * The contract is saved to the storage after the rule is modified.
553    *
554    * @return Licence extracted from contract (contract rule)
555    */

556   public Licence performPull()
557   {
558     if (pullCounter == 0) return null;
559     if (pullCounter > 0) pullCounter--;
560     Licence lic = (Licence)licence.clone();
561     if (lic.getText().length() == 0) lic.setText(parentContract.getDefaultLicenceText());
562     parentContract.saveToStorage();
563     return lic;
564   }
565   
566   /**
567    * Can ContractRule accept push - does ConractRule allow it?
568    *
569    * @param bundleInfo identification of bundle
570    * @param nodeInfo identification of destination node
571    * @param nodePassedInDefaults was destnination node accepted by "push defaults" in contract?
572    * @return true if rule can accept "push"
573    */

574   public boolean passPush(BundleInfo bundleInfo, NodeInfo nodeInfo, boolean nodePassedInDefaults)
575   {
576     if (pushDestinationNodes == null && !nodePassedInDefaults) return false;
577     if (!isValid()) return false;
578     if (!isPush) return false;
579     if (!software.pass(bundleInfo)) return false;
580     if (pushDestinationNodes != null && pushDestinationNodes.pass(nodeInfo) == null) return false;
581     if (pushCounter == 0) return false;
582     return true;
583   }
584
585   /**
586    * Performs "push" on the rule. Returned Licence can be null,
587    * but only if "push" cannot be made (passPush would fail).
588    * <p>
589    * The contract is saved to the storage after the rule is modified.
590    *
591    * @param nodeInfo identification of destination node
592    * @return Licence extracted from contract (contract rule)
593    */

594   public Licence performPush(NodeInfo nodeInfo)
595   {
596     if (pushCounter == 0) return null;
597     NodeNameLicList.NodeLicPair nlp = null;
598     if (pushDestinationNodes != null) nlp = pushDestinationNodes.pass(nodeInfo);
599     else nlp = parentContract.getDefaultPushDestinationNodes().pass(nodeInfo);
600     if (nlp == null) return null;
601     
602     Licence lic = (Licence)licence.clone();
603     if (nlp.numberOfLicences != Licence.ONE_IMPLICIT_LICENCE) lic.setNumberOfCopies(nlp.numberOfLicences);
604     if (lic.getText().length() == 0) lic.setText(parentContract.getDefaultLicenceText());
605     if (pushCounter > 0)
606     {
607       pushCounter--;
608       parentContract.saveToStorage();
609     }
610     return lic;
611   }
612 }
613
Popular Tags