KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > SOFA > SOFAnet > Core > NetOps


1 /*
2  * NetOps.java
3  *
4  * Created on 31. bøezen 2004, 17:05
5  */

6
7 package SOFA.SOFAnet.Core;
8
9 import SOFA.SOFAnet.Repository.*;
10 import SOFA.SOFAnet.Transport.*;
11 import SOFA.SOFAnode.TR.Impl.*;
12 import SOFA.SOFAnode.TR.*;
13 import java.util.*;
14 import java.io.*;
15
16 /**
17  * Network operations of the SOFAnet.
18  *
19  * @author Ladislav Sobr
20  */

21 public class NetOps
22 {
23   private Repository rep;
24   private TransportInterface transport;
25   private LocalOps localOps;
26   private ShareOps shareOps;
27   
28   private static class PushContractRule
29   {
30     public String JavaDoc nodeName;
31     public String JavaDoc contractID;
32     public String JavaDoc contractRule;
33     public InputTrigger inputTrigger;
34     
35     public PushContractRule(String JavaDoc nodeName, String JavaDoc contractID, String JavaDoc contractRule, InputTrigger inputTrigger)
36     {
37       this.nodeName = nodeName;
38       this.contractID = contractID;
39       this.contractRule = contractRule;
40       this.inputTrigger = inputTrigger;
41     }
42   }
43     
44   /** Creates a new instance of NetOps */
45   public NetOps()
46   {
47   }
48   
49   public void setRepository(Repository repository)
50   {
51     rep = repository;
52   }
53
54   public void setTransportInterface(TransportInterface transport)
55   {
56     this.transport = transport;
57   }
58   
59   public void setLocalOps(LocalOps localOps)
60   {
61     this.localOps = localOps;
62   }
63
64   public void setShareOps(ShareOps shareOps)
65   {
66     this.shareOps = shareOps;
67   }
68
69   
70   /**
71    * Tests whether node accepts push.
72    * <p>
73    * Synchronous (waits for completion).
74    * <p>
75    * Input:
76    * <ul>
77    * <li> bundleName
78    * <li> offer
79    * <li> sourceNodeName &nbsp;&nbsp;<i> name of pushing node</i>
80    * </ul>
81    * <p>
82    * Output: none
83    *
84    * @param params Input data for the call
85    * @return true if push is acceptable
86    */

87   public boolean isPushAcceptable(IOParams params) throws CoreException
88   {
89     String JavaDoc bundleName = params.getBundleName();
90     String JavaDoc nodeName = params.getSourceNodeName();
91     boolean offer = params.isOffer();
92     
93     BundleInfo bundleInfo = new BundleInfo();
94     try
95     {
96       bundleInfo.fromBundleName(bundleName);
97     }
98     catch (BundleInfo.InvalidBundleNameException e)
99     {
100       throw new CoreException("Push acceptance of bundle (or bundle offer) '" + bundleName + "' failed: Invalid name of bundle", e);
101     }
102     
103     NodeInfo nodeInfo = new NodeInfo();
104     try
105     {
106       nodeInfo.setNodeName(nodeName);
107     }
108     catch (NodeInfo.InvalidNodeNameException e)
109     {
110       return false;
111     }
112     
113     InputTriggers inputTriggers = rep.getInputTriggers();
114     
115     synchronized (inputTriggers) {
116     synchronized (inputTriggers.map)
117     {
118       Iterator it = inputTriggers.map.values().iterator();
119       while (it.hasNext())
120       {
121         InputTrigger inputTrigger = (InputTrigger)it.next();
122
123         int bundleType = inputTrigger.getBundleType();
124         
125         if (!inputTrigger.isPushSource()) continue;
126         if (offer && bundleType != InputTrigger.BUNDLETYPE_OFFER && bundleType != InputTrigger.BUNDLETYPE_ALL) continue;
127         if (!offer && bundleType != InputTrigger.BUNDLETYPE_FULL && bundleType != InputTrigger.BUNDLETYPE_ALL) continue;
128
129         if (!inputTrigger.isValid()) continue;
130
131         BundleNameFilter bundleFilter = inputTrigger.getBundleFilter();
132         NodeNameFilter nodeFilter = inputTrigger.getNodeFilter();
133         
134         if (bundleFilter != null && !bundleFilter.pass(bundleInfo) ||
135             nodeFilter != null && !nodeFilter.pass(nodeInfo)) continue;
136         
137         return true;
138       }
139     } //inputTriggers.map
140
} //inputTriggers
141

142     return false;
143   }
144   
145   /**
146    * Stores bundle/bundle offer/licence in the repository and preforms input triggers.
147    * <p>
148    * Synchronous (waits for completion).
149    * <p>
150    * Input:
151    * <ul>
152    * <li> bundleName
153    * <li> bundleData
154    * <li> offer
155    * <li> sourceNodeName &nbsp;&nbsp;<i> name of pushing node</i>
156    * <li> licence &nbsp;&nbsp;<i> can be null</i>
157    * </ul>
158    * <p>
159    * Output: none
160    *
161    * @param params Input data for the call
162    */

163   public void deliverBundle(IOParams params, boolean push) throws CoreException
164   {
165     String JavaDoc bundleName = params.getBundleName();
166     String JavaDoc nodeName = params.getSourceNodeName();
167     BundleData bundleData = params.getBundleData();
168     Licence licence = params.getLicence();
169     boolean offer = params.isOffer();
170
171     if (offer) Reporter.startInfo("Delivering bundle offer '" + bundleName + " from node '" + nodeName + "' to local node");
172     else Reporter.startInfo("Delivering bundle '" + bundleName + " from node '" + nodeName + "' to local node");
173     
174     BundleInfo bundleInfo = new BundleInfo();
175     try
176     {
177       bundleInfo.fromBundleName(bundleName);
178     }
179     catch (BundleInfo.InvalidBundleNameException e)
180     {
181       throw new CoreException("Delivery of bundle (or bundle offer) '" + bundleName + "' failed: Invalid name of bundle", e);
182     }
183     
184     BinBundles binBundles = rep.getBinBundles();
185     LocalInfos localInfos = rep.getLocalInfos();
186     Licences licences = rep.getLicences();
187     BundleOffers bundleOffers = rep.getBundleOffers();
188
189     if (!offer)
190     {
191       synchronized (binBundles) {
192       synchronized (licences)
193       {
194         BundleInfo binBundle = binBundles.getBinBundle(bundleName);
195         LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
196         Licence lic = licences.getLicence(bundleName);
197
198         if (binBundle != null || lic != null || localInfo != null)
199         {
200           throw new CoreException("Delivery of bundle '" + bundleName + "' failed: Bundle is already present");
201         }
202
203         binBundle = binBundles.addBinBundle(bundleName);
204
205         if (binBundle == null)
206         {
207           throw new CoreException("Delivery of bundle '" + bundleName + "' failed: Cannot add bundle to binary bundles");
208         }
209
210         if (!bundleData.copyToFile(binBundle.getFile(), true))
211         {
212           bundleData.delete();
213           binBundles.deleteBinBundle(bundleName);
214           throw new CoreException("Delivery of bundle '" + bundleName + "' failed: Error occured while copying bundle to binary bundles");
215         }
216
217         bundleData.delete();
218         bundleData = null;
219
220         if (licence != null && !licence.isEmpty())
221         {
222           lic = licences.addLicence(bundleName, licence.getType(), licence.getNumberOfCopies(),
223                                     licence.getValidFrom(), licence.getValidTo(), licence.getText());
224           
225           if (lic == null)
226           {
227             binBundles.deleteBinBundle(bundleName);
228             throw new CoreException("Delivery of bundle '" + bundleName + "' failed: Cannot add licence for bundle");
229           }
230         }
231       } //licences
232
} //binBundles
233

234     }
235     else
236     {
237       //bundle offer
238

239       BundleImpl bundleOff = new BundleImpl();
240       try
241       {
242         bundleOff._read(new FileInputStream(bundleData.getFile()));
243       }
244       catch (IOException e)
245       {
246         throw new CoreException("Delivery of bundle offer '" + bundleName + "' failed while decompressing bundle", e);
247       }
248       
249       String JavaDoc sourceNodeName = "";
250       ComponentInfo[] components = bundleOff.getComponents();
251       
252       if (components.length == 0)
253       {
254         throw new CoreException("Delivery of bundle offer '" + bundleName + "' failed: Empty bundle offer");
255       }
256       
257       ComponentInfoImpl[] myComponents = new ComponentInfoImpl[components.length];
258       for (int i = 0; i < components.length; i++)
259       {
260         if (i == 0)
261         {
262           sourceNodeName = components[i].getLocation();
263           if (!sourceNodeName.startsWith("sofa://"))
264           {
265             bundleOff = null;
266             throw new CoreException("Delivery of bundle offer '" + bundleName + "' failed: Invalid name of source node in bundle offer or not an bundle offer");
267           }
268         }
269         else
270         {
271           if (sourceNodeName.compareTo(components[i].getLocation()) != 0)
272           {
273             bundleOff = null;
274             throw new CoreException("Delivery of bundle offer '" + bundleName + "' failed: Inconsistent names of source node in bundle offer");
275           }
276         }
277         myComponents[i] = new ComponentInfoImpl(components[i].getName(), components[i].getImplementationVersion());
278       }
279       
280       bundleOff = null;
281
282       BundleOffer bundleOffer = bundleOffers.addBundleOffer(bundleName, sourceNodeName, myComponents);
283       
284       if (bundleOffer == null)
285       {
286         throw new CoreException("Delivery of bundle offer '" + bundleName + "' failed: Cannot add bundle offer");
287       }
288     }
289
290     //delete temporary file with bundle
291
if (bundleData != null)
292     {
293       bundleData.delete();
294       bundleData = null;
295     }
296     
297     //perform input triggers
298
int source;
299     if (push) source = InputTrigger.SOURCE_PUSH;
300     else source = InputTrigger.SOURCE_PULL;
301     performInputTriggers(bundleName, nodeName, source, offer);
302
303     if (offer) Reporter.stopInfo("Bundle offer '" + bundleName + " from node '" + nodeName + "' delivered to local node");
304     else Reporter.stopInfo("Bundle '" + bundleName + " from node '" + nodeName + "' delivered to local node");
305   }
306
307   /**
308    * Wrapper for deliverBundle in push mode.
309    */

310   public void deliverBundlePush(IOParams params) throws CoreException
311   {
312     deliverBundle(params, true);
313   }
314   
315   /**
316    * Wrapper for deliverBundle in pull mode.
317    */

318   public void deliverBundlePull(IOParams params) throws CoreException
319   {
320     deliverBundle(params, false);
321   }
322   
323   /**
324    * Tests whether node accepts pull.
325    * <p>
326    * Synchronous (waits for completion).
327    * <p>
328    * Input:
329    * <ul>
330    * <li> bundleName
331    * <li> sourceNodeName &nbsp;&nbsp;<i> name of pulling node</i>
332    * <li> contractID &nbsp;&nbsp;<i> if output trigger has contract than contract's ID must match contractID to consider the output trigger</i>
333    * </ul>
334    * <p>
335    * Output: none
336    *
337    * @param params Input data for the call
338    * @return true if pull is acceptable
339    */

340   public boolean isPullAcceptable(IOParams params) throws CoreException
341   {
342     String JavaDoc bundleName = params.getBundleName();
343     String JavaDoc nodeName = params.getSourceNodeName();
344     String JavaDoc contractID = params.getContractID();
345
346     BundleInfo bundleInfo = new BundleInfo();
347     try
348     {
349       bundleInfo.fromBundleName(bundleName);
350     }
351     catch (BundleInfo.InvalidBundleNameException e)
352     {
353       throw new CoreException("Pull acceptance of bundle '" + bundleName + "' failed: Invalid name of bundle", e);
354     }
355     
356     NodeInfo nodeInfo = new NodeInfo();
357     try
358     {
359       nodeInfo.setNodeName(nodeName);
360     }
361     catch (NodeInfo.InvalidNodeNameException e)
362     {
363       return false;
364     }
365     
366
367     BinBundles binBundles = rep.getBinBundles();
368     OutputTriggers outputTriggers = rep.getOutputTriggers();
369     Contracts contracts = rep.getContracts();
370     Licences licences = rep.getLicences();
371
372     //test presence of binary bundle
373
BundleInfo binBundle = binBundles.getBinBundle(bundleName);
374     if (binBundle == null) return false;
375     binBundle = null;
376
377     synchronized (outputTriggers) {
378     synchronized (outputTriggers.map)
379     {
380       Iterator it = outputTriggers.map.values().iterator();
381       while (it.hasNext())
382       {
383         OutputTrigger outputTrigger = (OutputTrigger)it.next();
384
385         if (!outputTrigger.isValid()) continue;
386
387         BundleNameFilter bundleFilter = outputTrigger.getBundleFilter();
388         NodeNameFilter nodeFilter = outputTrigger.getNodeFilter();
389
390         if (bundleFilter != null && !bundleFilter.pass(bundleInfo) ||
391             nodeFilter != null && !nodeFilter.pass(nodeInfo)) continue;
392
393         if (outputTrigger.isContract())
394         {
395           if (outputTrigger.getContractID().compareTo(contractID) != 0) continue;
396           if (contracts.passPull(bundleInfo, nodeInfo, outputTrigger.getContractID(), outputTrigger.getContractRule()) == null) continue;
397         }
398         else
399         {
400           synchronized (licences)
401           {
402             Licence lic = licences.getLicence(bundleName);
403             if (lic != null && lic.withCopies() && lic.getNumberOfCopies() == 0) continue;
404           } //licences
405
}
406
407         return true;
408       }
409     } //outputTriggers.map
410
} //outputTriggers
411

412     return false;
413   }
414
415   /**
416    * Pull bundle from repository.
417    * <p>
418    * Synchronous (waits for completion).
419    * <p>
420    * Input:
421    * <ul>
422    * <li> bundleName
423    * <li> sourceNodeName &nbsp;&nbsp;<i> name of pulling node</i>
424    * <li> contractID &nbsp;&nbsp;<i> if output trigger has contract than contract's ID must match contractID to consider the output trigger</i>
425    * </ul>
426    * <p>
427    * Output (on OK):
428    * <ul>
429    * <li> bundleName
430    * <li> bundleData
431    * <li> licence
432    * <li> errCode == 0
433    * </ul>
434    * <p>
435    * Output (on error):
436    * <ul>
437    * <li> errCode
438    * <ul>
439    * <li> 1 == Cannot find binary bundle
440    * <li> 2 == Cannot create BundleData for bundle
441    * <li> 3 == Pull not allowed
442    * </ul>
443    * </ul>
444    *
445    * @param params Input/Output data for the call
446    */

447   public void preparePulledBundle(IOParams params) throws CoreException
448   {
449     String JavaDoc bundleName = params.getBundleName();
450     String JavaDoc nodeName = params.getSourceNodeName();
451     String JavaDoc contractID = params.getContractID();
452
453     Reporter.startInfo("Preparing bundle '" + bundleName + "' for pull by node '" + nodeName + "'");
454     
455     BundleInfo bundleInfo = new BundleInfo();
456     try
457     {
458       bundleInfo.fromBundleName(bundleName);
459     }
460     catch (BundleInfo.InvalidBundleNameException e)
461     {
462       throw new CoreException("Preparation of pulled bundle '" + bundleName + "' failed: Invalid name of bundle", e);
463     }
464     
465     NodeInfo nodeInfo = new NodeInfo();
466     try
467     {
468       nodeInfo.setNodeName(nodeName);
469     }
470     catch (NodeInfo.InvalidNodeNameException e)
471     {
472       throw new CoreException("Preparation of pulled bundle '" + bundleName + "' failed: Invalid name of SOFA node: " + nodeName, e);
473     }
474     
475     BinBundles binBundles = rep.getBinBundles();
476     OutputTriggers outputTriggers = rep.getOutputTriggers();
477     Contracts contracts = rep.getContracts();
478     Licences licences = rep.getLicences();
479
480     synchronized (binBundles) {
481     synchronized (outputTriggers) {
482     synchronized (outputTriggers.map) {
483     synchronized (contracts) {
484     synchronized (licences)
485     {
486       //test presence of binary bundle
487
BundleInfo binBundle = binBundles.getBinBundle(bundleName);
488       if (binBundle == null)
489       {
490         params.setErrCode(1);
491         return;
492       }
493
494       Iterator it = outputTriggers.map.values().iterator();
495       while (it.hasNext())
496       {
497         OutputTrigger outputTrigger = (OutputTrigger)it.next();
498
499         if (!outputTrigger.isValid()) continue;
500
501         BundleNameFilter bundleFilter = outputTrigger.getBundleFilter();
502         NodeNameFilter nodeFilter = outputTrigger.getNodeFilter();
503
504         if (bundleFilter != null && !bundleFilter.pass(bundleInfo) ||
505             nodeFilter != null && !nodeFilter.pass(nodeInfo)) continue;
506
507         ContractRule contractRule = null;
508         Licence lic = null;
509
510         if (outputTrigger.isContract())
511         {
512           if (outputTrigger.getContractID().compareTo(contractID) != 0) continue;
513           contractRule = contracts.passPull(bundleInfo, nodeInfo, outputTrigger.getContractID(), outputTrigger.getContractRule());
514           if (contractRule == null) continue;
515         }
516         else
517         {
518           lic = licences.getLicence(bundleName);
519           if (lic != null && lic.withCopies() && lic.getNumberOfCopies() == 0) continue;
520         }
521
522         //we found output trigger allowing pull
523
BundleData bundleData = new BundleData(binBundle.getFile(), true);
524         if (bundleData.getFile() == null)
525         {
526           params.setErrCode(2);
527         }
528
529         params.setBundleData(bundleData);
530
531         Licence licence = null;
532
533         if (outputTrigger.isContract())
534         {
535           licence = contractRule.performPull();
536           
537           //remove contract rule, contract and output trigger if requested
538
if (contractRule.toBeDeleted())
539           {
540             Contract contract = contractRule.getParentContract();
541             contract.getRules().remove(contractRule.getName());
542             if (contract.toBeDeleted()) contracts.deleteContract(contract.getName());
543             else contract.saveToStorage();
544             
545             if (outputTrigger.getAutoDelete()) outputTriggers.deleteOutputTrigger(outputTrigger.getName());
546           }
547         }
548         else
549         {
550           if (lic != null)
551           {
552             licence = (Licence) lic.clone();
553
554             if (lic.withCopies())
555             {
556               licence.setNumberOfCopies(1);
557               lic.decreaseNumberOfCopies(1);
558               lic.saveToStorage();
559             }
560           }
561         }
562
563         params.setLicence(licence);
564         params.setErrCode(0);
565         Reporter.stopInfo("Bundle '" + bundleName + "' pulled by node '" + nodeName + "'");
566         return;
567       }
568     } //licences
569
} //contracts
570
} //outputTriggers.map
571
} //outputTriggers
572
} //binBundles
573

574     params.setErrCode(3);
575     return;
576   }
577   
578   /**
579    * Performs actions of input triggers of the bundle (or bundle offer) when it arrives.
580    * <p>
581    * Actions are described in the input triggers. It can be:
582    * <ul>
583    * <li>install
584    * <li>share
585    * <li>allow_pull
586    * <li>push
587    * <li>push_offer
588    * <li>delete
589    * </ul>
590    * <p>
591    * All matching input triggers are considered together - first we find out which actions shoud be performed
592    * from all input triggers. After that we distribute available licences among actions. Than the actions are
593    * performed.
594    *
595    * @param bundleName name of bundle (or bundle offer)
596    * @param nodeName name of source node of the bundle (even if the bundle is created on the node: for source == InputTrigger.SOURCE_MADE)
597    * @param source how the bundle appeared on the node (creted/pulled/pushed) - see InputTrigger.SOURCE_... constants
598    * @param offer if true, bundle offer arrived not the classical bundle
599    */

600   public void performInputTriggers(String JavaDoc bundleName, String JavaDoc nodeName, int source, boolean offer) throws CoreException
601   {
602     boolean actionInstall = false;
603     boolean actionShare = false;
604     boolean actionAllowPull = false;
605     boolean actionPush = false;
606     boolean actionPushOffer = false;
607     boolean actionDelete = false;
608
609     Reporter.startInfo("Performing input triggers on bundle '" + bundleName + "' from node '" + nodeName + "'");
610     
611     int asNoLicences = 0;
612     ShareGroups asShareGroups = null;
613     NodeNameFilter asNodeFilter = null;
614     boolean asEquality = false;
615     List alpOutputTriggers = new LinkedList();
616     NodeNameLicList apNoContract = new NodeNameLicList();
617     List apContract = new LinkedList();
618     NodeNameList apoNodeNameList = new NodeNameList();
619     
620     BundleInfo bundleInfo = new BundleInfo();
621     try
622     {
623       bundleInfo.fromBundleName(bundleName);
624     }
625     catch (BundleInfo.InvalidBundleNameException e)
626     {
627       throw new CoreException("Performing input triggers on '" + bundleName + "' failed: Invalid name of bundle", e);
628     }
629     
630     NodeInfo nodeInfo = new NodeInfo();
631     try
632     {
633       nodeInfo.setNodeName(nodeName);
634     }
635     catch (NodeInfo.InvalidNodeNameException e)
636     {
637       throw new CoreException("Performing input triggers on '" + bundleName + "' failed: Invalid name of SOFA node: " + nodeName, e);
638     }
639     
640     BinBundles binBundles = rep.getBinBundles();
641     InputTriggers inputTriggers = rep.getInputTriggers();
642     OutputTriggers outputTriggers = rep.getOutputTriggers();
643     Contracts contracts = rep.getContracts();
644     LocalInfos localInfos = rep.getLocalInfos();
645     Licences licences = rep.getLicences();
646     BundleOffers bundleOffers = rep.getBundleOffers();
647     
648     synchronized (inputTriggers) {
649     synchronized (licences) {
650     synchronized (inputTriggers.map)
651     {
652       Licence lic = licences.getLicence(bundleName);
653       
654       Iterator it = inputTriggers.map.values().iterator();
655       while (it.hasNext())
656       {
657         InputTrigger inputTrigger = (InputTrigger)it.next();
658         
659         int src = inputTrigger.getSource();
660         int bundleType = inputTrigger.getBundleType();
661         
662         if ((src & source) == 0) continue;
663         if (offer && bundleType != InputTrigger.BUNDLETYPE_OFFER && bundleType != InputTrigger.BUNDLETYPE_ALL) continue;
664         if (!offer && bundleType != InputTrigger.BUNDLETYPE_FULL && bundleType != InputTrigger.BUNDLETYPE_ALL) continue;
665         
666         if (!inputTrigger.isValid()) continue;
667
668         BundleNameFilter bundleFilter = inputTrigger.getBundleFilter();
669         NodeNameFilter nodeFilter = inputTrigger.getNodeFilter();
670         
671         if (bundleFilter != null && !bundleFilter.pass(bundleInfo) ||
672             nodeFilter != null && !nodeFilter.pass(nodeInfo)) continue;
673         
674         if ((inputTrigger.getActions() & InputTrigger.ACTION_INSTALL) != 0 && !offer)
675         {
676           actionInstall = true;
677         }
678         
679         if ((inputTrigger.getActions() & InputTrigger.ACTION_SHARE) != 0 && !offer)
680         {
681           actionShare = true;
682           int asNoLic = inputTrigger.getAsNoLicences();
683           if (asNoLic == Licence.ONE_IMPLICIT_LICENCE) asNoLicences++;
684           else if (asNoLic == Licence.ALL_LICENCES) asNoLicences = Licence.ALL_LICENCES;
685           else asNoLicences += asNoLic;
686           ShareGroups sg = inputTrigger.getAsShareGroups();
687           if (sg != null)
688           {
689             if (asShareGroups == null) asShareGroups = new ShareGroups();
690             asShareGroups.add(sg);
691           }
692           NodeNameFilter nnf = inputTrigger.getAsNodeFilter();
693           if (nnf != null)
694           {
695             if (asNodeFilter == null) asNodeFilter = new NodeNameFilter();
696             asNodeFilter.add(nnf);
697           }
698           
699           if (inputTrigger.getAsEquality()) asEquality = true;
700         }
701         
702         if ((inputTrigger.getActions() & InputTrigger.ACTION_ALLOW_PULL) != 0 && !offer)
703         {
704           actionAllowPull = true;
705           OutputTrigger outputTrigger = inputTrigger.getAlpOutputTrigger();
706           if (outputTrigger != null) alpOutputTriggers.add(outputTrigger.clone());
707         }
708         
709         if ((inputTrigger.getActions() & InputTrigger.ACTION_PUSH) != 0)
710         {
711           if (!offer)
712           {
713             actionPush = true;
714             
715             //we have standard binary bundle, not only bundle offer
716
if (inputTrigger.isContract())
717             {
718               NodeNameLicList apNodeNameLicList = inputTrigger.getApNodeNameLicList();
719               String JavaDoc contractID = inputTrigger.getContractID();
720               String JavaDoc contractRule = inputTrigger.getContractRule();
721
722               if (apNodeNameLicList != null)
723               {
724                 List li = apNodeNameLicList.getList();
725                 synchronized (li)
726                 {
727                   Iterator it2 = li.iterator();
728                   while (it2.hasNext())
729                   {
730                     NodeNameLicList.NodeLicPair nlp = (NodeNameLicList.NodeLicPair)it2.next();
731                     apContract.add(new PushContractRule(nlp.nodeName, contractID, contractRule, inputTrigger));
732                   }
733                 }
734               }
735             }
736             else
737             {
738               apNoContract.add(inputTrigger.getApNodeNameLicList());
739             }
740           }
741           else
742           {
743             actionPushOffer = true;
744             
745             //we have bundle offer, so act like if in "action PUSH OFFER"
746

747             NodeNameLicList apNodeNameLicList = inputTrigger.getApNodeNameLicList();
748             if (apNodeNameLicList != null)
749             {
750               List li = apNodeNameLicList.getList();
751               synchronized (li)
752               {
753                 Iterator it2 = li.iterator();
754                 while (it2.hasNext())
755                 {
756                   NodeNameLicList.NodeLicPair nlp = (NodeNameLicList.NodeLicPair)it2.next();
757                   apoNodeNameList.add(nlp.nodeName);
758                 }
759               }
760             }
761             
762           }
763         }
764         
765         if ((inputTrigger.getActions() & InputTrigger.ACTION_PUSH_OFFER) != 0 && !offer)
766         {
767           actionPushOffer = true;
768           apoNodeNameList.add(inputTrigger.getApoNodeNameList());
769         }
770
771         if ((inputTrigger.getActions() & InputTrigger.ACTION_DELETE) != 0)
772         {
773           actionDelete = true;
774         }
775       }
776       
777       
778       //count licence copies for the actions
779

780       if (lic != null && lic.withCopies())
781       {
782         int remains = lic.getNumberOfCopies();
783         
784         //add licence "to sharing" if install should be done but sharing has 0 licence copies
785
if (actionInstall && asNoLicences == 0) asNoLicences = 1;
786         
787         //change ONE_IMPLICIT_LICENCE to 1
788
if (asNoLicences == Licence.ONE_IMPLICIT_LICENCE) asNoLicences = 1;
789
790         Iterator it2;
791         
792         it2 = apNoContract.getList().iterator();
793         while (it2.hasNext())
794         {
795           NodeNameLicList.NodeLicPair nlp = (NodeNameLicList.NodeLicPair)it2.next();
796           if (nlp.numberOfLicences == Licence.ONE_IMPLICIT_LICENCE) nlp.numberOfLicences = 1;
797         }
798         
799         //handle all licence copies with specific number
800
if (asNoLicences != Licence.ALL_LICENCES)
801         {
802           if (asNoLicences <= remains) remains -= asNoLicences;
803           else
804           {
805             asNoLicences = remains;
806             remains = 0;
807           }
808         }
809         
810         it2 = apNoContract.getList().iterator();
811         while (it2.hasNext())
812         {
813           NodeNameLicList.NodeLicPair nlp = (NodeNameLicList.NodeLicPair)it2.next();
814           if (nlp.numberOfLicences != Licence.ALL_LICENCES)
815           {
816             if (nlp.numberOfLicences <= remains) remains -= nlp.numberOfLicences;
817             else
818             {
819               nlp.numberOfLicences = remains;
820               remains = 0;
821             }
822           }
823         }
824         
825         //handle "all remaining copies" flag (Licence.ALL_LICENCES)
826
if (asNoLicences == Licence.ALL_LICENCES)
827         {
828           asNoLicences = remains;
829           remains = 0;
830         }
831         
832         it2 = apNoContract.getList().iterator();
833         while (it2.hasNext())
834         {
835           NodeNameLicList.NodeLicPair nlp = (NodeNameLicList.NodeLicPair)it2.next();
836           if (nlp.numberOfLicences == Licence.ALL_LICENCES)
837           {
838             nlp.numberOfLicences = remains;
839             remains = 0;
840           }
841         }
842         
843         //now all informations about licence copies should contain concrete number of licences
844
}
845       else
846       {
847         //-no restrictions on licences
848
//-change ONE_IMPLICIT_LICENCE to ALL_LICENCES
849

850         //add licence "to sharing" if install should be done but sharing has 0 licence copies
851
if (actionInstall && asNoLicences == 0) asNoLicences = Licence.ALL_LICENCES;
852         
853         if (asNoLicences == Licence.ONE_IMPLICIT_LICENCE) asNoLicences = Licence.ALL_LICENCES;
854
855         Iterator it2;
856         
857         it2 = apNoContract.getList().iterator();
858         while (it2.hasNext())
859         {
860           NodeNameLicList.NodeLicPair nlp = (NodeNameLicList.NodeLicPair)it2.next();
861           if (nlp.numberOfLicences == Licence.ONE_IMPLICIT_LICENCE) nlp.numberOfLicences = Licence.ALL_LICENCES;
862         }
863       }
864     } //inputTriggers.map
865
} //licences
866
} //inputTriggers
867

868     
869     //perform install action
870
if (actionInstall)
871     {
872       if (asNoLicences != 0)
873       {
874         try
875         {
876           localOps.installBundle(bundleName, true);
877         }
878         catch (CoreException e)
879         {
880           Reporter.error("Performing input triggers on '" + bundleName + "' failed: Cannot install bundle", e);
881         }
882       }
883       else Reporter.error("Performing input triggers on '" + bundleName + "': Cannot install bundle - not enough licence copies");
884     }
885     
886     //perform share action
887
if (actionShare)
888     {
889       if (asNoLicences != 0)
890       {
891         try
892         {
893           shareOps.shareBundle(bundleName, asNoLicences, asShareGroups, asNodeFilter, asEquality, true);
894         }
895         catch (CoreException e)
896         {
897           Reporter.error("Performing input triggers on '" + bundleName + "' failed: Cannot share bundle", e);
898         }
899       }
900       else Reporter.error("Performing input triggers on '" + bundleName + "' failed: Cannot share bundle - not enough licence copies");
901     }
902     
903     //perform allow_pull action
904
if (actionAllowPull)
905     {
906       synchronized (outputTriggers)
907       {
908         Iterator it2 = alpOutputTriggers.iterator();
909         while (it2.hasNext())
910         {
911           OutputTrigger outputTrigger = (OutputTrigger)it2.next();
912           outputTriggers.addOutputTrigger("", true, outputTrigger.getDescription(), outputTrigger.getAutoDelete(),
913               outputTrigger.getBundleFilter(), outputTrigger.getNodeFilter(), outputTrigger.getValidFrom(),
914               outputTrigger.getValidTo(), outputTrigger.getContractID(), outputTrigger.getContractRule());
915         }
916       } //outputTriggers
917
}
918
919     //perform push action
920
if (actionPush)
921     {
922       IOParams ioParams = new IOParams();
923       
924       ioParams.setBundleName(bundleName);
925
926       //get BundleData
927
BundleInfo bundle = null;
928       BundleData bundleData = null;
929       synchronized (binBundles)
930       {
931         bundle = binBundles.getBinBundle(bundleName);
932         
933         if (bundle != null)
934         {
935           bundleData = new BundleData(bundle.getFile(), true);
936           if (bundleData.getFile() != null)
937           {
938             ioParams.setBundleData(bundleData);
939           }
940           else
941           {
942             Reporter.error("Performing input triggers on '" + bundleName + "' failed: Cannot create BundleData");
943           }
944         }
945         else
946         {
947           Reporter.error("Performing input triggers on '" + bundleName + "' failed: Cannot find binary bundle");
948         }
949       } //binBundles
950

951       if (bundleData != null)
952       {
953         ioParams.setOffer(false);
954         ioParams.setPriority(IOParams.PRIORITY_DISTRIBUTION);
955         
956         int numNodes = 0;
957         
958         
959         //handle destination nodes with contracts
960
synchronized (inputTriggers) {
961         synchronized (contracts)
962         {
963           Iterator it = apContract.iterator();
964           while (it.hasNext())
965           {
966             PushContractRule pcr = (PushContractRule)it.next();
967             Licence licence = contracts.performPush(bundleName, pcr.nodeName, pcr.contractID, pcr.contractRule);
968             if (licence != null)
969             {
970               if (numNodes == 0)
971               {
972                 ioParams.setNodeName(pcr.nodeName);
973                 if (!licence.isEmpty()) ioParams.setLicence(licence);
974                 else ioParams.setLicence(null);
975               }
976               else
977               {
978                 IOParams.OtherNode otherNode = new IOParams.OtherNode();
979                 otherNode.nodeName = pcr.nodeName;
980                 if (!licence.isEmpty()) otherNode.licence = licence;
981                 else otherNode.licence = null;
982                 ioParams.addOtherNode(otherNode);
983               }
984               numNodes++;
985               
986               //remove contract rule, contract and input trigger if requested
987
ContractRule contractRule = contracts.getContractRule(pcr.contractID, pcr.contractRule);
988               if (contractRule.toBeDeleted())
989               {
990                 Contract contract = contractRule.getParentContract();
991                 contract.getRules().remove(contractRule.getName());
992                 if (contract.toBeDeleted()) contracts.deleteContract(contract.getName());
993                 else contract.saveToStorage();
994
995                 if (pcr.inputTrigger.getAutoDelete()) inputTriggers.deleteInputTrigger(pcr.inputTrigger.getName());
996               }
997             }
998           }
999           
1000        } //contracts
1001
} //inputTriggers
1002

1003        boolean maybeDelete = false;
1004        boolean deleteBundle = false;
1005        
1006        //handle destination nodes without contracts
1007
synchronized (licences)
1008        {
1009          Licence lic = licences.getLicence(bundleName);
1010          
1011          Iterator it = apNoContract.getList().iterator();
1012          while (it.hasNext())
1013          {
1014            NodeNameLicList.NodeLicPair nlp = (NodeNameLicList.NodeLicPair)it.next();
1015            
1016            Licence licence = null;
1017            boolean push = false;
1018
1019            //we know that nlp.numberOfLicences is either >= 0 or Licence.ALL_LICENCES
1020
if (nlp.numberOfLicences > 0)
1021            {
1022              if (lic != null)
1023              {
1024                if (lic.withCopies())
1025                {
1026                  int num = lic.getNumberOfCopies();
1027                  if (num < nlp.numberOfLicences) nlp.numberOfLicences = num;
1028                  if (num > 0)
1029                  {
1030                    licence = (Licence)lic.clone();
1031                    licence.setNumberOfCopies(nlp.numberOfLicences);
1032                    lic.decreaseNumberOfCopies(nlp.numberOfLicences);
1033                    lic.saveToStorage();
1034                    push = true;
1035                  }
1036                }
1037                else
1038                {
1039                  licence = (Licence)lic.clone();
1040                  licence.setNumberOfCopies(nlp.numberOfLicences);
1041                  push = true;
1042                }
1043              }
1044              else
1045              {
1046                licence = new Licence();
1047                licence.setNumberOfCopies(nlp.numberOfLicences);
1048                push = true;
1049              }
1050            }
1051            else if (nlp.numberOfLicences == Licence.ALL_LICENCES)
1052            {
1053              if (lic != null)
1054              {
1055                if (lic.withCopies())
1056                {
1057                  //this shouldn't happen
1058
int num = lic.getNumberOfCopies();
1059                  if (num > 0)
1060                  {
1061                    licence = (Licence)lic.clone();
1062                    licence.setNumberOfCopies(num);
1063                    lic.decreaseNumberOfCopies(num);
1064                    lic.saveToStorage();
1065                    push = true;
1066                  }
1067                }
1068                else
1069                {
1070                  licence = (Licence)lic.clone();
1071                  push = true;
1072                }
1073              }
1074              else push = true;
1075            }
1076            
1077            if (push)
1078            {
1079              if (numNodes == 0)
1080              {
1081                ioParams.setNodeName(nlp.nodeName);
1082                ioParams.setLicence(licence);
1083              }
1084              else
1085              {
1086                IOParams.OtherNode otherNode = new IOParams.OtherNode();
1087                otherNode.nodeName = nlp.nodeName;
1088                otherNode.licence = licence;
1089                ioParams.addOtherNode(otherNode);
1090              }
1091              numNodes++;
1092            }
1093          }
1094          
1095          if (lic != null && lic.getType() == Licence.TYPE_PHYSICAL && lic.getNumberOfCopies() == 0) maybeDelete = true;
1096
1097        } //licences
1098

1099        //test whether to delete binary bundle because of no licence
1100
if (maybeDelete)
1101        {
1102          synchronized (localInfos)
1103          {
1104            LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
1105            if (localInfo == null || !localInfo.isInstalled() && localInfo.getLicence().getNumberOfCopies() == 0) deleteBundle = true;
1106          } //localInfos
1107
}
1108        
1109        //perform push on transport layer
1110
if (numNodes > 0)
1111        {
1112          try
1113          {
1114            transport.push(ioParams);
1115          }
1116          catch (TransportException e)
1117          {
1118            Reporter.error("Performing input triggers on '" + bundleName + "' failed: Cannot push bundle", e);
1119          }
1120        }
1121        
1122        bundleData = null;
1123        bundle = null;
1124        
1125        //we have to delete binary bundle because of lack of licences
1126
if (deleteBundle)
1127        {
1128          try
1129          {
1130            localOps.deleteBinaryBundle(bundleName);
1131          }
1132          catch (CoreException e)
1133          {
1134            Reporter.error("Performing input triggers on '" + bundleName + "' failed: Cannot delete binary bundle", e);
1135          }
1136        }
1137        
1138      }
1139    } //actionPush
1140

1141    //perform push_offer action
1142
if (actionPushOffer)
1143    {
1144      IOParams ioParams = new IOParams();
1145 
1146      ioParams.setBundleName(bundleName);
1147      
1148      //prepare BundleData
1149
BundleData bundleData = null;
1150     
1151      synchronized (binBundles) {
1152      synchronized (bundleOffers)
1153      {
1154        BundleOffer bundleOffer = bundleOffers.getBundleOffer(bundleName);
1155        
1156        if (bundleOffer != null)
1157        {
1158          bundleData = bundleOffer.generateBundleData();
1159          if (bundleData == null)
1160          {
1161            Reporter.error("Performing input triggers on '" + bundleName + "' failed: Cannot create BundleData for bundle offer");
1162          }
1163          else ioParams.setBundleData(bundleData);
1164        }
1165        else
1166        {
1167          try
1168          {
1169            bundleData = generateBundleDataForBundleOfferFromBinBundle(bundleName);
1170          }
1171          catch (CoreException e)
1172          {
1173            Reporter.error("Performing input triggers on '" + bundleName + "' failed while creatind BundleData for bundle offer", e);
1174          }
1175          
1176          ioParams.setBundleData(bundleData);
1177        }
1178      } //binBundles
1179
} //bundleOffers
1180

1181      if (bundleData != null)
1182      {
1183        bundleData = null; //we don't need it any more
1184

1185        ioParams.setOffer(true);
1186        ioParams.setPriority(IOParams.PRIORITY_DISTRIBUTION);
1187        
1188        //prepare list of destination nodes
1189
int numNodes = 0;
1190        Iterator it = apoNodeNameList.getList().iterator();
1191        while (it.hasNext())
1192        {
1193          String JavaDoc outNodeName = (String JavaDoc)it.next();
1194          
1195          if (numNodes == 0) ioParams.setNodeName(outNodeName);
1196          else
1197          {
1198            IOParams.OtherNode otherNode = new IOParams.OtherNode();
1199            otherNode.nodeName = outNodeName;
1200            ioParams.addOtherNode(otherNode);
1201          }
1202          numNodes++;
1203        }
1204        
1205        //perform push on transport layer
1206
if (numNodes > 0)
1207        {
1208          try
1209          {
1210            transport.push(ioParams);
1211          }
1212          catch (TransportException e)
1213          {
1214            Reporter.error("Performing input triggers on '" + bundleName + "' failed: Cannot push bundle offer", e);
1215          }
1216        }
1217      }
1218    } //actionPushOffer
1219

1220    //perform delete action
1221
if (actionDelete)
1222    {
1223      synchronized (binBundles) {
1224      synchronized (localInfos) {
1225      synchronized (licences) {
1226      synchronized (bundleOffers)
1227      {
1228        binBundles.deleteBinBundle(bundleName);
1229        bundleOffers.deleteBundleOffer(bundleName);
1230
1231        LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
1232
1233        if (localInfo != null)
1234        {
1235          Reporter.error("Performing input triggers on '" + bundleName + "' failed: Bundle cannot be completely deleted because it is installed and/or shared");
1236        }
1237        else
1238        {
1239          licences.deleteLicence(bundleName);
1240        }
1241      } //bundleOffers
1242
} //localInfos
1243
} //licences
1244
} //binBundles
1245
}
1246    
1247    Reporter.stopInfo("Input triggers on bundle '" + bundleName + "' from node '" + nodeName + "' performed");
1248  }
1249
1250  /**
1251   * Creates bundle offer from binary bundle on the local node.
1252   *
1253   * @param bundleName name of bundle
1254   * @param overwrite if true the potentially existing bundle offer of that name is deleted first; else if bundle offer of that name exist an exception is thrown
1255   */

1256  public void createBundleOfferFromBinBundle(String JavaDoc bundleName, boolean overwrite) throws CoreException
1257  {
1258    BinBundles binBundles = rep.getBinBundles();
1259    BundleOffers bundleOffers = rep.getBundleOffers();
1260
1261    Reporter.startInfo("Creating bundle offer for bundle '" + bundleName + "'");
1262    
1263    synchronized (binBundles) {
1264    synchronized (bundleOffers)
1265    {
1266      BundleOffer bundleOffer = bundleOffers.getBundleOffer(bundleName);
1267      if (bundleOffer != null)
1268      {
1269        throw new CoreException("Creation of bundle offer from binary bundle '" + bundleName + "' failed: Bundle offer already exists");
1270      }
1271      
1272      BundleInfo binBundle = binBundles.getBinBundle(bundleName);
1273      if (binBundle == null)
1274      {
1275        throw new CoreException("Creation of bundle offer from binary bundle '" + bundleName + "' failed: Cannot find binary bundle");
1276      }
1277
1278      //decompress binary bundle to the temp and create BundleImpl structure
1279
BundleImpl bundle = new BundleImpl();
1280      try
1281      {
1282        bundle._read(new FileInputStream(binBundle.getFile()));
1283      }
1284      catch (IOException e)
1285      {
1286        new CoreException("Creation of bundle offer from binary bundle '" + bundleName + "' failed while decompressing bundle", e);
1287      }
1288      
1289      //if bundle offer exits, delete it
1290
if (bundleOffer != null) bundleOffers.deleteBundleOffer(bundleName);
1291      
1292      //add new bundle offer
1293
ComponentInfo[] components = bundle.getComponents();
1294      if (components.length == 0)
1295      {
1296        new CoreException("Creation of bundle offer from binary bundle '" + bundleName + "' failed: Empty bundle");
1297      }
1298      
1299      ComponentInfoImpl[] myComponents = new ComponentInfoImpl[components.length];
1300      for (int i = 0; i < components.length; i++)
1301      {
1302        myComponents[i] = new ComponentInfoImpl(components[i].getName(), components[i].getImplementationVersion());
1303      }
1304      
1305      String JavaDoc sourceNodeName = NodeInfo.getLocalNodeName();
1306      bundleOffers.addBundleOffer(bundleName, sourceNodeName, myComponents);
1307      
1308      bundle = null;
1309
1310      Reporter.stopInfo("Bundle offer for bundle '" + bundleName + "' successfully created");
1311      
1312    } //binBundles
1313
} //bundleOffers
1314
}
1315
1316  /**
1317   * Creates BundleData version of bundle offer that is generated from binary bundle (but not stored among bundle offers!).
1318   *
1319   * @param bundleName name of bundle
1320   * @return BundleData version of generated bundle offer
1321   */

1322  public BundleData generateBundleDataForBundleOfferFromBinBundle(String JavaDoc bundleName) throws CoreException
1323  {
1324    BinBundles binBundles = rep.getBinBundles();
1325
1326    synchronized (binBundles)
1327    {
1328      BundleInfo binBundle = binBundles.getBinBundle(bundleName);
1329      if (binBundle == null)
1330      {
1331        throw new CoreException("Creation of bundle offer file from binary bundle '" + bundleName + "' failed: Cannot find binary bundle");
1332      }
1333
1334      //decompress binary bundle to the temp and create BundleImpl structure
1335
BundleImpl bundle = new BundleImpl();
1336      try
1337      {
1338        bundle._read(new FileInputStream(binBundle.getFile()));
1339      }
1340      catch (IOException e)
1341      {
1342        new CoreException("Creation of BundleData for bundle offer from binary bundle '" + bundleName + "' failed while decompressing bundle", e);
1343      }
1344      
1345      BundleImpl bundleOff = new BundleImpl();
1346      ComponentInfo[] components = bundle.getComponents();
1347      if (components.length == 0)
1348      {
1349        throw new CoreException("Creation of BundleData for bundle offer from binary bundle '" + bundleName + "' failed: Empty bundle");
1350      }
1351      
1352      for (int i = 0; i < components.length; i++)
1353      {
1354        bundleOff.add(new ComponentInfoImpl(components[i].getName(), components[i].getImplementationVersion()), BundleImpl.NO_FILES);
1355      }
1356
1357      bundle = null;
1358      
1359      File tempFile = new File(BundleData.generateFilename());
1360      
1361      try
1362      {
1363        FileOutputStream os = new FileOutputStream(tempFile);
1364        bundleOff._write(os);
1365        os.close();
1366      }
1367      catch (Exception JavaDoc e)
1368      {
1369        throw new CoreException("Creation of BundleData for bundle offer from binary bundle '" + bundleName + "' failed while saving binary bundle to file", e);
1370      }
1371      
1372      bundleOff = null;
1373
1374      return new BundleData(tempFile, false);
1375    } //binBundles
1376
}
1377
1378  /**
1379   * Tests whether push of the bundle or bundle offer is accepted by destination node.
1380   * This is "client" of the "testPush" operation.
1381   *
1382   * @param bundleName name of bundle (or bundle offer)
1383   * @param nodeName name of destination node
1384   * @param offer if true push of bundle offer is tested; otherwise classical bundle is concerned
1385   * @return true if the push can be accepted by destination node
1386   */

1387  public boolean testPush(String JavaDoc bundleName, String JavaDoc nodeName, boolean offer) throws CoreException
1388  {
1389    IOParams ioParams = new IOParams();
1390    
1391    ioParams.setBundleName(bundleName);
1392    ioParams.setNodeName(nodeName);
1393    ioParams.setOffer(offer);
1394    
1395     //perform testPush on transport layer
1396
try
1397    {
1398      transport.testPush(ioParams);
1399    }
1400    catch (TransportException e)
1401    {
1402      throw new CoreException("Test push of '" + bundleName + "' failed", e);
1403    }
1404    
1405    return ioParams.getErrCode() == 0;
1406  }
1407  
1408  /**
1409   * Pushes bundle to the destination node.
1410   * This is "client" of the "push" operation.
1411   *
1412   * @param bundleName name of bundle
1413   * @param nodeName name of destination node
1414   * @param numberOfLicences positive integer of Licence.ALL_LICENCES ; no effect if contract is present
1415   */

1416  public void pushBundle(String JavaDoc bundleName, String JavaDoc nodeName, int numberOfLicences) throws CoreException
1417  {
1418    Reporter.startInfo("Pushing bundle '" + bundleName + "' to node '" + nodeName + "'");
1419    
1420    BundleInfo bundleInfo = new BundleInfo();
1421    try
1422    {
1423      bundleInfo.fromBundleName(bundleName);
1424    }
1425    catch (BundleInfo.InvalidBundleNameException e)
1426    {
1427      throw new CoreException("Push of bundle '" + bundleName + "' failed: Invalid name of bundle", e);
1428    }
1429    
1430    NodeInfo nodeInfo = new NodeInfo();
1431    try
1432    {
1433      nodeInfo.setNodeName(nodeName);
1434    }
1435    catch (NodeInfo.InvalidNodeNameException e)
1436    {
1437      throw new CoreException("Push of bundle '" + bundleName + "' failed: Invalid name of SOFA node: " + nodeName, e);
1438    }
1439 
1440    IOParams ioParams = new IOParams();
1441    
1442    ioParams.setBundleName(bundleName);
1443    ioParams.setNodeName(nodeName);
1444    ioParams.setOffer(false);
1445 
1446    BinBundles binBundles = rep.getBinBundles();
1447    Contracts contracts = rep.getContracts();
1448    LocalInfos localInfos = rep.getLocalInfos();
1449    Licences licences = rep.getLicences();
1450
1451    //get BundleData
1452
BundleInfo bundle = null;
1453    BundleData bundleData = null;
1454    synchronized (binBundles)
1455    {
1456      bundle = binBundles.getBinBundle(bundleName);
1457
1458      if (bundle == null) throw new CoreException("Push of bundle '" + bundleName + "' failed: Cannot find binary bundle");
1459
1460      bundleData = new BundleData(bundle.getFile(), true);
1461      if (bundleData.getFile() == null) throw new CoreException("Push of bundle '" + bundleName + "' failed: Cannot create BundleData");
1462
1463      ioParams.setBundleData(bundleData);
1464    } //binBundles
1465

1466    ioParams.setPriority(IOParams.PRIORITY_INTERACTIVE);
1467
1468    Licence licence = null;
1469    boolean deleteBundle = false;
1470    
1471    //check whether contracts are involved
1472
synchronized (contracts)
1473    {
1474      ContractRule contractRule = contracts.passPush(bundleInfo, nodeInfo);
1475      if (contractRule != null) licence = contractRule.performPush(nodeInfo);
1476    } //contracts
1477

1478    if (licence == null)
1479    {
1480      boolean maybeDelete = false;
1481      
1482      //try licence files
1483
synchronized (licences)
1484      {
1485        Licence lic = licences.getLicence(bundleName);
1486        
1487        if (lic != null)
1488        {
1489          if (lic.withCopies())
1490          {
1491            int licNum = lic.getNumberOfCopies();
1492            if (numberOfLicences == Licence.ALL_LICENCES) numberOfLicences = licNum;
1493            
1494            if (numberOfLicences > licNum)
1495            {
1496              throw new CoreException("Push of bundle '" + bundleName + "' failed: Not enough licence copies");
1497            }
1498            
1499            licence = (Licence)lic.clone();
1500            licence.setNumberOfCopies(numberOfLicences);
1501            lic.decreaseNumberOfCopies(numberOfLicences);
1502            lic.saveToStorage();
1503            
1504            if (lic.getType() == Licence.TYPE_PHYSICAL && lic.getNumberOfCopies() == 0) maybeDelete = true;
1505          }
1506          else
1507          {
1508            licence = (Licence)lic.clone();
1509            if (numberOfLicences >= 0) licence.setNumberOfCopies(numberOfLicences);
1510          }
1511        }
1512        else
1513        {
1514          if (numberOfLicences >= 0)
1515          {
1516            licence = new Licence();
1517            licence.setNumberOfCopies(numberOfLicences);
1518          }
1519        }
1520      } //licences
1521

1522      //test whether to delete binary bundle because of no licence
1523
if (maybeDelete)
1524      {
1525        synchronized (localInfos)
1526        {
1527          LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
1528          if (localInfo == null || !localInfo.isInstalled() && localInfo.getLicence().getNumberOfCopies() == 0) deleteBundle = true;
1529        } //localInfos
1530
}
1531    }
1532    
1533    ioParams.setLicence(licence);
1534    
1535    //perform push on transport layer
1536
try
1537    {
1538      transport.push(ioParams);
1539    }
1540    catch (TransportException e)
1541    {
1542      throw new CoreException("Push of bundle '" + bundleName + "' failed", e);
1543    }
1544    
1545    //we have to delete binary bundle because of lack of licences
1546
if (deleteBundle)
1547    {
1548      try
1549      {
1550        localOps.deleteBinaryBundle(bundleName);
1551      }
1552      catch (CoreException e)
1553      {
1554        throw new CoreException("Push of bundle '" + bundleName + "' failed: Cannot delete binary bundle", e);
1555      }
1556    }
1557    
1558    Reporter.stopInfo("Bundle '" + bundleName + "' scheduled to push to node '" + nodeName + "'");
1559  }
1560
1561  /**
1562   * Pushes bundle offer to the destination node. Bundle offer must already exist on the local node.
1563   * This is "client" of the "push" operation.
1564   *
1565   * @param bundleName name of bundle (or bundle offer)
1566   * @param nodeName name of destination node
1567   */

1568  public void pushBundleOffer(String JavaDoc bundleName, String JavaDoc nodeName) throws CoreException
1569  {
1570    Reporter.startInfo("Pushing bundle offer '" + bundleName + "' to node '" + nodeName + "'");
1571    
1572    BundleInfo bundleInfo = new BundleInfo();
1573    try
1574    {
1575      bundleInfo.fromBundleName(bundleName);
1576    }
1577    catch (BundleInfo.InvalidBundleNameException e)
1578    {
1579      throw new CoreException("Push of bundle offer '" + bundleName + "' failed: Invalid name of bundle offer", e);
1580    }
1581    
1582    NodeInfo nodeInfo = new NodeInfo();
1583    try
1584    {
1585      nodeInfo.setNodeName(nodeName);
1586    }
1587    catch (NodeInfo.InvalidNodeNameException e)
1588    {
1589      throw new CoreException("Push of bundle offer '" + bundleName + "' failed: Invalid name of SOFA node: " + nodeName, e);
1590    }
1591 
1592    IOParams ioParams = new IOParams();
1593    
1594    ioParams.setBundleName(bundleName);
1595    ioParams.setNodeName(nodeName);
1596    ioParams.setOffer(true);
1597  
1598    BundleData bundleData = null;
1599    BundleOffers bundleOffers = rep.getBundleOffers();
1600    
1601    synchronized (bundleOffers)
1602    {
1603      BundleOffer bundleOffer = bundleOffers.getBundleOffer(bundleName);
1604      if (bundleOffer == null) throw new CoreException("Push of bundle offer '" + bundleName + "' failed: Cannot find bundle offer");
1605
1606      bundleData = bundleOffer.generateBundleData();
1607      if (bundleData == null) throw new CoreException("Push of bundle failed'" + bundleName + "' failed: Cannot create BundleData from bundle offer");
1608    } //bundleOffers
1609

1610    ioParams.setPriority(IOParams.PRIORITY_INTERACTIVE);
1611    ioParams.setBundleData(bundleData);
1612    ioParams.setLicence(null);
1613    
1614    //perform push on transport layer
1615
try
1616    {
1617      transport.push(ioParams);
1618    }
1619    catch (TransportException e)
1620    {
1621      throw new CoreException("Push of bundle offer'" + bundleName + "' failed", e);
1622    }
1623    
1624    Reporter.stopInfo("Bundle offer '" + bundleName + "' scheduled to push to node '" + nodeName + "'");
1625
1626  }
1627  
1628  /**
1629   * Tests whether pull (download) of the bundle is accepted by source node.
1630   * This is "client" of the "testPull" operation.
1631   *
1632   * @param bundleName name of bundle
1633   * @param nodeName name of source node
1634   * @param contractID ID of the contract that we have at the source node ; use empty string for no contract
1635   * @return true if the pull can be accepted by the source node
1636   */

1637  public boolean testPull(String JavaDoc bundleName, String JavaDoc nodeName, String JavaDoc contractID) throws CoreException
1638  {
1639    IOParams ioParams = new IOParams();
1640    
1641    ioParams.setBundleName(bundleName);
1642    ioParams.setNodeName(nodeName);
1643    ioParams.setContractID(contractID);
1644    
1645    //perform testPull on transport layer
1646
try
1647    {
1648      transport.testPull(ioParams);
1649    }
1650    catch (TransportException e)
1651    {
1652      throw new CoreException("Test pull of '" + bundleName + "' failed", e);
1653    }
1654    
1655    return ioParams.getErrCode() == 0;
1656  }
1657  
1658  
1659  /**
1660   * Pulls (downloads) bundle from the source node.
1661   * This is "client" of the "pull" operation.
1662   * <p>
1663   * The actions of input triggers are performed when the bundle arrives.
1664   * <p>
1665   * This "pull" is just an order to the transport layer to do that action. It needen't be performed immediatelly!
1666   *
1667   * @param bundleName name of bundle
1668   * @param nodeName name of source node
1669   * @param contractID ID of the contract that we have at the source node ; use empty string for no contract
1670   */

1671  public void pullBundle(String JavaDoc bundleName, String JavaDoc nodeName, String JavaDoc contractID) throws CoreException
1672  {
1673    Reporter.startInfo("Pulling bundle '" + bundleName + "' from node '" + nodeName + "'");
1674    
1675    BundleInfo bundleInfo = new BundleInfo();
1676    try
1677    {
1678      bundleInfo.fromBundleName(bundleName);
1679    }
1680    catch (BundleInfo.InvalidBundleNameException e)
1681    {
1682      throw new CoreException("Pull of bundle '" + bundleName + "' failed: Invalid name of bundle", e);
1683    }
1684    
1685    NodeInfo nodeInfo = new NodeInfo();
1686    try
1687    {
1688      nodeInfo.setNodeName(nodeName);
1689    }
1690    catch (NodeInfo.InvalidNodeNameException e)
1691    {
1692      throw new CoreException("Pull of bundle '" + bundleName + "' failed: Invalid name of SOFA node: " + nodeName, e);
1693    }
1694 
1695    BinBundles binBundles = rep.getBinBundles();
1696    LocalInfos localInfos = rep.getLocalInfos();
1697    Licences licences = rep.getLicences();
1698    
1699    if (binBundles.getBinBundle(bundleName) != null ||
1700        licences.getLicence(bundleName) != null ||
1701        localInfos.getLocalInfo(bundleName) != null)
1702    {
1703      throw new CoreException("Pull of bundle '" + bundleName + "' failed: Bundle is already present (binary bundle/licence/local info)");
1704    }
1705        
1706    IOParams ioParams = new IOParams();
1707    
1708    ioParams.setBundleName(bundleName);
1709    ioParams.setNodeName(nodeName);
1710    ioParams.setContractID(contractID);
1711    ioParams.setPriority(IOParams.PRIORITY_INTERACTIVE);
1712   
1713    //perform testPull on transport layer
1714
try
1715    {
1716      transport.pull(ioParams);
1717    }
1718    catch (TransportException e)
1719    {
1720      throw new CoreException("Pull of '" + bundleName + "' failed", e);
1721    }
1722    
1723    Reporter.stopInfo("Bundle '" + bundleName + "' scheduled to pull from node '" + nodeName + "'");
1724  }
1725  
1726  /**
1727   * Pulls (downloads) bundle from the source node.
1728   * This is "client" of the "synchroPull" operation.
1729   * <p>
1730   * The actions of input triggers are performed when the bundle arrives.
1731   * <p>
1732   * This "pull" is performed immediatelly and it is finished before return of the function.
1733   *
1734   * @param bundleName name of bundle
1735   * @param nodeName name of source node
1736   * @param contractID ID of the contract that we have at the source node ; use empty string for no contract
1737   */

1738  public void synchroPullBundle(String JavaDoc bundleName, String JavaDoc nodeName, String JavaDoc contractID) throws CoreException
1739  {
1740    Reporter.startInfo("Synchonously pulling bundle '" + bundleName + "' from node '" + nodeName + "'");
1741    
1742    BundleInfo bundleInfo = new BundleInfo();
1743    try
1744    {
1745      bundleInfo.fromBundleName(bundleName);
1746    }
1747    catch (BundleInfo.InvalidBundleNameException e)
1748    {
1749      throw new CoreException("Pull of bundle '" + bundleName + "' failed: Invalid name of bundle", e);
1750    }
1751    
1752    NodeInfo nodeInfo = new NodeInfo();
1753    try
1754    {
1755      nodeInfo.setNodeName(nodeName);
1756    }
1757    catch (NodeInfo.InvalidNodeNameException e)
1758    {
1759      throw new CoreException("Pull of bundle '" + bundleName + "' failed: Invalid name of SOFA node: " + nodeName, e);
1760    }
1761 
1762    BinBundles binBundles = rep.getBinBundles();
1763    LocalInfos localInfos = rep.getLocalInfos();
1764    Licences licences = rep.getLicences();
1765    
1766    if (binBundles.getBinBundle(bundleName) != null ||
1767        licences.getLicence(bundleName) != null ||
1768        localInfos.getLocalInfo(bundleName) != null)
1769    {
1770      throw new CoreException("Pull of bundle '" + bundleName + "' failed: Bundle is already present (binary bundle/licence/local info)");
1771    }
1772        
1773    IOParams ioParams = new IOParams();
1774    
1775    ioParams.setBundleName(bundleName);
1776    ioParams.setNodeName(nodeName);
1777    ioParams.setContractID(contractID);
1778    ioParams.setPriority(IOParams.PRIORITY_INTERACTIVE);
1779   
1780    //perform testPull on transport layer
1781
try
1782    {
1783      transport.synchroPull(ioParams);
1784    }
1785    catch (TransportException e)
1786    {
1787      throw new CoreException("Pull of '" + bundleName + "' failed", e);
1788    }
1789    
1790    int errCode = ioParams.getErrCode();
1791    if (errCode != 0)
1792    {
1793      switch (errCode)
1794      {
1795      case 1: throw new CoreException("Pull of '" + bundleName + "' failed: Cannot find binary bundle on remote node");
1796      case 2: throw new CoreException("Pull of '" + bundleName + "' failed: Cannot create BundleData for bundle");
1797      case 3: throw new CoreException("Pull of '" + bundleName + "' failed: Pull not allowed by remote node");
1798      default: throw new CoreException("Pull of '" + bundleName + "' failed: Transport layer failed");
1799      }
1800    }
1801    
1802    ioParams.setBundleName(bundleName);
1803    ioParams.setSourceNodeName(nodeName);
1804    
1805    deliverBundlePull(ioParams);
1806    
1807    Reporter.stopInfo("Bundle '" + bundleName + "' synchronously pulled from node '" + nodeName + "'");
1808  }
1809 
1810  /**
1811   * Generates input and output triggers that performs the rules introduced by the contract.
1812   *
1813   * @param contractID ID (name) of contract
1814   * @param firstDelete if true all input and output triggers that belongs to the contract are deleted first
1815   */

1816  public void generateTriggersOfContract(String JavaDoc contractID, boolean firstDelete) throws CoreException
1817  {
1818    Reporter.startInfo("Generating triggers of contract '" + contractID + "'");
1819    
1820    Contracts contracts = rep.getContracts();
1821    InputTriggers inputTriggers = rep.getInputTriggers();
1822    OutputTriggers outputTriggers = rep.getOutputTriggers();
1823    
1824    Contract contract = contracts.getContract(contractID);
1825    if (contract == null) throw new CoreException("Cannot find Contract '" + contractID + "'");
1826    
1827    contract.generateTriggers(firstDelete, inputTriggers, outputTriggers);
1828    
1829    Reporter.stopInfo("Triggers of contract '" + contractID + "' generated");
1830  }
1831  
1832  /**
1833   * Deletes input and output triggers belongs to the contract
1834   *
1835   * @param contractID ID (name) of contract
1836   */

1837  public void deleteTriggersOfContract(String JavaDoc contractID) throws CoreException
1838  {
1839    Reporter.startInfo("Deleting triggers of contract '" + contractID + "'");
1840    
1841    Contracts contracts = rep.getContracts();
1842    InputTriggers inputTriggers = rep.getInputTriggers();
1843    OutputTriggers outputTriggers = rep.getOutputTriggers();
1844    
1845    Contract contract = contracts.getContract(contractID);
1846    if (contract == null) throw new CoreException("Cannot find Contract '" + contractID + "'");
1847    
1848    contract.deleteTriggers(inputTriggers, outputTriggers);
1849
1850    Reporter.stopInfo("Triggers of contract '" + contractID + "' deleted");
1851  }
1852}
Popular Tags