KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * LocalOps.java
3  *
4  * Created on 20. bøezen 2004, 14:03
5  */

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

23 public class LocalOps
24 {
25   private TRInterface tr;
26   private TransportInterface transport;
27   private Repository rep;
28   private NetOps netOps;
29   private ShareOps shareOps;
30   private SearchOps searchOps;
31   
32   /** Creates a new instance of LocalOps */
33   public LocalOps()
34   {
35   }
36   
37   public void setRepository(Repository repository)
38   {
39     rep = repository;
40   }
41   
42   public void setTRInterface(TRInterface tr)
43   {
44     this.tr = tr;
45   }
46   
47   public void setTransportInterface(TransportInterface transport)
48   {
49     this.transport = transport;
50   }
51   
52   public void setNetOps(NetOps netOps)
53   {
54     this.netOps = netOps;
55   }
56   
57   public void setShareOps(ShareOps shareOps)
58   {
59     this.shareOps = shareOps;
60   }
61   
62   public void setSearchOps(SearchOps searchOps)
63   {
64     this.searchOps = searchOps;
65   }
66   
67   /**
68    * Tests whether bundle is installed
69    *
70    * @param bundleName name of bundle
71    * @return true if installed, else false
72    */

73   public boolean isBundleInstalled(String JavaDoc bundleName)
74   {
75     LocalInfos localInfos = rep.getLocalInfos();
76     synchronized (localInfos)
77     {
78       LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
79       if (localInfo == null) return false;
80       return localInfo.isInstalled();
81     }
82   }
83   
84   /**
85    * Installs bundle
86    *
87    * @param bundleName name of bundle
88    * @param reinstall true: installed bundle is uninstalled and installed again; false: bundle must not be already installed
89    */

90   public void installBundle(String JavaDoc bundleName, boolean reinstall) throws CoreException
91   {
92     Reporter.startInfo("Installing bundle '" + bundleName + "'");
93     
94     BundleInfo bundleInfo = new BundleInfo();
95     try
96     {
97       bundleInfo.fromBundleName(bundleName);
98     }
99     catch (BundleInfo.InvalidBundleNameException e)
100     {
101       throw new CoreException("Installation of bundle '" + bundleName + "' failed: Invalid name of bundle", e);
102     }
103     
104     BinBundles binBundles = rep.getBinBundles();
105     BundleContents installedBundleContents = rep.getInstalledBundleContents();
106     LocalInfos localInfos = rep.getLocalInfos();
107     Licences licences = rep.getLicences();
108     BinBundles shareClientCache = rep.getShareClientCache();
109     
110     synchronized (binBundles) {
111     synchronized (installedBundleContents) {
112     synchronized (localInfos) {
113     synchronized (licences) {
114     synchronized (shareClientCache)
115     {
116       BundleInfo binBundle = null;
117       
118       
119       //get local info and if present, check STATE_SHARE_CLIENT state
120
LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
121       if (localInfo != null && localInfo.areShareClientModes())
122       {
123         if (localInfo.isShareClient())
124         {
125           //get binary version of bundle from share client cache
126
binBundle = shareClientCache.getBinBundle(bundleName);
127           if (binBundle == null) throw new CoreException("Installation of bundle '" + bundleName + "' failed: Cannot find binary version of bundle in share client cache");
128         }
129         else throw new CoreException("Installation of bundle '" + bundleName + "' failed: Bundle has pre-share client active.");
130       }
131       else
132       {
133         //get binary bundle
134
binBundle = binBundles.getBinBundle(bundleName);
135         if (binBundle == null) throw new CoreException("Installation of bundle '" + bundleName + "' failed: Cannot find binary version of bundle");
136       }
137       
138       
139       //perform uninstall if needed
140
if (isBundleInstalled(bundleName))
141       {
142         if (reinstall) uninstallBundle(bundleName, true, false, true);
143         else throw new CoreException("Installation of bundle '" + bundleName + "' failed: Bundle is already installed");
144       }
145
146       //modify local info - if not present, create it using licences
147
if (localInfo != null)
148       {
149         //we already have local info, so just mark it "installed"
150

151         Licence licence = localInfo.getLicence();
152         if (!licence.isValid()) throw new CoreException("Installation of bundle '" + bundleName + "' failed: Licence is not valid (expired)");
153         
154         localInfo.setInstalled(true);
155         localInfo.saveToStorage();
156       }
157       else
158       {
159         //we have to build local info
160

161         //try to get licence from Licences
162
Licence licence = null;
163         Licence lic = licences.getLicence(bundleName);
164
165         if (lic != null)
166         {
167           //we have found it!
168
if (!lic.isValid()) throw new CoreException("Installation of bundle '" + bundleName + "' failed: Licence is not valid (expired)");
169           if (lic.getNumberOfCopies() == 0) throw new CoreException("Installation of bundle '" + bundleName + "' failed: No licence copy available in licence file");
170
171           licence = (Licence)lic.clone();
172
173           //take one copy
174
if (licence.getNumberOfCopies() == Licence.WITHOUT_COPIES)
175           {
176             //ok, nothing to do
177
}
178           else
179           {
180             licence.setNumberOfCopies(1);
181             lic.decreaseNumberOfCopies(1);
182             lic.saveToStorage();
183           }
184         }
185         else licence = new Licence();
186         
187         localInfo = localInfos.addLocalInfo(bundleName, licence, LocalInfo.STATE_INSTALLED, null, null, false, "");
188       }
189       
190     
191       //decompress binary bundle to the temp and create BundleImpl structure
192
BundleImpl bundle = new BundleImpl();
193       try
194       {
195         bundle._read(new FileInputStream(binBundle.getFile()));
196       }
197       catch (IOException e)
198       {
199         throw new CoreException("Installation of bundle '" + bundleName + "' failed while decompressing bundle", e);
200       }
201       
202
203       //add installed bundle
204
if (installedBundleContents.getBundleContent(bundleName) != null)
205       {
206         //incosistent repository - this shouldn't happen
207
installedBundleContents.deleteBundleContent(bundleName);
208       }
209
210       installedBundleContents.addBundleContent(bundleName, bundle.getComponents());
211         
212
213       //store bundle to TR
214
try
215       {
216         tr.storeBundle(bundle);
217       }
218       catch (TRException e)
219       {
220         throw new CoreException("Installation of bundle '" + bundleName + "' failed while storing bundle to TR", e);
221       }
222       
223       bundle = null;
224       
225     } //shareClientCache
226
} //licences
227
} //localInfos
228
} //installedBundleContents
229
} //binBundles
230

231     Reporter.stopInfo("Bundle '" + bundleName + "' successfully installed");
232   }
233   
234   /**
235    * Uninstalls bundle.
236    *
237    * @param bundleName name of bundle
238    * @param deleteComponents if true (usually) the components will be deleted in TR
239    * @param includingInterfaces if true, also interfaces of bundle will be removed from TR; if false just implementation
240    * @param force if true, all possible mentions of installed bundle will be removed even if the repository is in the incosistent state
241    */

242   public void uninstallBundle(String JavaDoc bundleName, boolean deleteComponents, boolean includingInterfaces, boolean force) throws CoreException
243   {
244     Reporter.startInfo("Uninstalling bundle '" + bundleName + "'");
245     
246     BundleInfo bundleInfo = new BundleInfo();
247     try
248     {
249       bundleInfo.fromBundleName(bundleName);
250     }
251     catch (BundleInfo.InvalidBundleNameException e)
252     {
253       throw new CoreException("Uninstallation of bundle '" + bundleName + "' failed: Invalid name of bundle", e);
254     }
255     
256     BundleContents installedBundleContents = rep.getInstalledBundleContents();
257     LocalInfos localInfos = rep.getLocalInfos();
258     Licences licences = rep.getLicences();
259     
260     synchronized (installedBundleContents) {
261     synchronized (localInfos) {
262     synchronized (licences)
263     {
264       //get local info
265
LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
266       if (localInfo != null)
267       {
268         if (localInfo.isInMemory()) throw new CoreException("Uninstallation of bundle '" + bundleName + "' failed: Bundle in use (components loaded in memory)");
269         
270         if (!force && !localInfo.isInstalled()) throw new CoreException("Uninstallation of bundle '" + bundleName + "' failed: Bundle is not installed");
271         
272         localInfo.setInstalled(false);
273         if (localInfo.getState() == LocalInfo.STATE_NONE)
274         {
275           //we have to return licences and delete local info
276
Licence licence = localInfo.getLicence();
277           Licence lic = licences.getLicence(bundleName);
278           if (lic != null && licence.withCopies() && lic.withCopies())
279           {
280             //ok, licence file for bundle exists, so return licences
281
lic.increaseNumberOfCopies(licence.getNumberOfCopies());
282             lic.saveToStorage();
283           }
284           
285           localInfos.deleteLocalInfo(bundleName);
286         }
287         else
288         {
289           localInfo.saveToStorage();
290         }
291       }
292       else
293       {
294         if (force) Reporter.error("Incosistent repository - cannot find LocalInfo for " + bundleName);
295         else throw new CoreException("Uninstallation of bundle '" + bundleName + "' failed: Incosistent repository - cannot find LocalInfo");
296       }
297       
298       //get installed bundle
299
BundleContent installedBundleContent = installedBundleContents.getBundleContent(bundleName);
300       if (installedBundleContent != null)
301       {
302         if (deleteComponents)
303         {
304           //delete bundle from TR
305
try
306           {
307             List components = installedBundleContent.getComponents();
308             tr.deleteComponents((ComponentInfo[])components.toArray(new ComponentInfoImpl[components.size()]), includingInterfaces, false);
309           }
310           catch (TRException e)
311           {
312             if (force) Reporter.error("Incosistent repository - deletion of bundle " + bundleName + " from TR failed");
313             else throw new CoreException("Uninstallation of bundle '" + bundleName + "' failed while deleting bundle from TR", e);
314           }
315         }
316         
317         //remove installed bundle
318
installedBundleContents.deleteBundleContent(bundleName);
319       }
320       else
321       {
322         if (force) Reporter.error("Incosistent repository - cannot find BundleContent for " + bundleName);
323         else throw new CoreException("Uninstallation of bundle '" + bundleName + "' failed: Incosistent repository - cannot find BundleContent");
324       }
325       
326     } //licences
327
} //localInfos
328
} //installedBundleContents
329

330     Reporter.stopInfo("Bundle '" + bundleName + "' uninstalled");
331   }
332   
333   /**
334    * Creates binary version of bundle from installed bundle.
335    *
336    * The actions of input triggers are then performed.
337    *
338    * @param bundleName name of bundle
339    * @param overwrite if binary version already exists, then if true, it is overwritten, else the exception is thrown
340    */

341   public void createBinaryBundle(String JavaDoc bundleName, boolean overwrite) throws CoreException
342   {
343     Reporter.startInfo("Creating binary bundle '" + bundleName + "'");
344
345     BundleInfo bundleInfo = new BundleInfo();
346     try
347     {
348       bundleInfo.fromBundleName(bundleName);
349     }
350     catch (BundleInfo.InvalidBundleNameException e)
351     {
352       throw new CoreException("Creation of binary bundle '" + bundleName + "' failed: Invalid name of bundle", e);
353     }
354     
355     BinBundles binBundles = rep.getBinBundles();
356     BundleContents installedBundleContents = rep.getInstalledBundleContents();
357     LocalInfos localInfos = rep.getLocalInfos();
358     
359     synchronized (binBundles) {
360     synchronized (installedBundleContents) {
361     synchronized (localInfos)
362     {
363       //get local info and check STATE_SHARE_CLIENT state
364
LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
365       if (localInfo == null || !localInfo.isInstalled()) throw new CoreException("Creation of binary bundle '" + bundleName + "' failed: Bundle is not installed");
366       if (localInfo != null && localInfo.areShareClientModes()) throw new CoreException("Creation of binary bundle '" + bundleName + "' failed: Creation of binary version of bundle provided by share client is forbidden");
367       
368       //get installed bundle
369
BundleContent installedBundleContent = installedBundleContents.getBundleContent(bundleName);
370       if (installedBundleContent == null) throw new CoreException("Creation of binary bundle '" + bundleName + "' failed: Cannot find installed version of bundle");
371       
372       //get components from TR
373
BundleImpl bundle = null;
374       try
375       {
376         List components = installedBundleContent.getComponents();
377         bundle = (BundleImpl) tr.getBundle(null, (ComponentInfo[])components.toArray(new ComponentInfoImpl[components.size()]), false);
378       }
379       catch (TRException e)
380       {
381         throw new CoreException("Creation of binary bundle '" + bundleName + "' failed while getting bundle from TR", e);
382       }
383       
384       //get binary bundle
385
BundleInfo binBundle = binBundles.getBinBundle(bundleName);
386       if (binBundle != null)
387       {
388         if (!overwrite) throw new CoreException("Creation of binary bundle '" + bundleName + "' failed: Binary version of bundle already exists");
389       }
390       else
391       {
392         //create binary bundle structure
393
binBundle = binBundles.addBinBundle(bundleName);
394         if (binBundle == null) throw new CoreException("Creation of binary bundle '" + bundleName + "' failed: Cannot create BinBundle structure");
395       }
396       
397       try
398       {
399         FileOutputStream os = new FileOutputStream(binBundle.getFile());
400         bundle._write(os);
401         os.close();
402       }
403       catch (Exception JavaDoc e)
404       {
405         binBundles.deleteBinBundle(bundleName);
406         throw new CoreException("Creation of binary bundle '" + bundleName + "' failed while saving binary bundle to file", e);
407       }
408       
409       bundle = null;
410       
411     } //localInfos
412
} //installedBundleContents
413
} //binBundles
414

415     String JavaDoc myNodeName = NodeInfo.getLocalNodeName();
416     
417     netOps.performInputTriggers(bundleName, myNodeName, InputTrigger.SOURCE_MADE, false);
418     
419     Reporter.stopInfo("Binary version of bundle '" + bundleName + "' created");
420   }
421
422   /**
423    * Creates BundleData version of bundle from installed bundle.
424    * Only for internal use of SOFAnet!!!!! It should be called only if no problem is expected.
425    * @param bundleName name of bundle
426    * @return BundleData with installed bundle, null otherwise
427    */

428   BundleData recreateBundleFromTR(String JavaDoc bundleName)
429   {
430     BundleInfo bundleInfo = new BundleInfo();
431     try
432     {
433       bundleInfo.fromBundleName(bundleName);
434     }
435     catch (BundleInfo.InvalidBundleNameException e)
436     {
437       return null;
438     }
439     
440     BundleContents installedBundleContents = rep.getInstalledBundleContents();
441     
442     synchronized (installedBundleContents)
443     {
444       //get installed bundle
445
BundleContent installedBundleContent = installedBundleContents.getBundleContent(bundleName);
446       if (installedBundleContent == null) return null;
447       
448       //get components from TR
449
BundleImpl bundle = null;
450       try
451       {
452         List components = installedBundleContent.getComponents();
453         bundle = (BundleImpl) tr.getBundle(null, (ComponentInfo[])components.toArray(new ComponentInfoImpl[components.size()]), false);
454       }
455       catch (TRException e)
456       {
457         return null;
458       }
459       
460       File tempFile = new File(BundleData.generateFilename());
461       
462       try
463       {
464         FileOutputStream os = new FileOutputStream(tempFile);
465         bundle._write(os);
466         os.close();
467       }
468       catch (Exception JavaDoc e)
469       {
470         bundle = null;
471         return null;
472       }
473       
474       bundle = null;
475
476       return new BundleData(tempFile, false);
477     } //installedBundleContents
478
}
479   
480   /**
481    * Deletes binary version of bundle.
482    *
483    * @param bundleName name of bundle
484    */

485   public void deleteBinaryBundle(String JavaDoc bundleName) throws CoreException
486   {
487     Reporter.startInfo("Deleting binary bundle '" + bundleName + "'");
488
489     BundleInfo bundleInfo = new BundleInfo();
490     try
491     {
492       bundleInfo.fromBundleName(bundleName);
493     }
494     catch (BundleInfo.InvalidBundleNameException e)
495     {
496       throw new CoreException("Deletion of binary bundle '" + bundleName + "' failed: Invalid name of bundle", e);
497     }
498
499     BinBundles binBundles = rep.getBinBundles();
500     
501     synchronized (binBundles)
502     {
503       //get binary bundle
504
BundleInfo binBundle = binBundles.getBinBundle(bundleName);
505       if (binBundle == null)
506       {
507         throw new CoreException("Deletion of binary bundle '" + bundleName + "' failed: Binary version of bundle is not present");
508       }
509       
510       try
511       {
512         boolean deleted = binBundle.getFile().delete();
513         if (!deleted) throw new CoreException("Deletion of binary bundle '" + bundleName + "' failed: The fail was not deleted");
514       }
515       catch (Exception JavaDoc e)
516       {
517         throw new CoreException("Deletion of binary bundle '" + bundleName + "' failed while deleting the file", e);
518       }
519       
520       binBundles.deleteBinBundle(bundleName);
521       
522       
523     } //binBundles
524

525     Reporter.stopInfo("Binary version of bundle '" + bundleName + "' deleted");
526   }
527
528   /**
529    * Deletes binary bundle and its licence.
530    * For successfull call bundle must not be installed or shared.
531    *
532    * @param bundleName name of bundle
533    */

534   public void deleteBundle(String JavaDoc bundleName) throws CoreException
535   {
536     Reporter.startInfo("Deleting bundle '" + bundleName + "'");
537     
538     BinBundles binBundles = rep.getBinBundles();
539     LocalInfos localInfos = rep.getLocalInfos();
540     Licences licences = rep.getLicences();
541   
542     synchronized (binBundles) {
543     synchronized (localInfos) {
544     synchronized (licences)
545     {
546       LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
547       if (localInfo != null)
548       {
549         throw new CoreException("Deletion of bundle '" + bundleName + "' failed: Bundle is installed and/or shared");
550       }
551
552       binBundles.deleteBinBundle(bundleName);
553       licences.deleteLicence(bundleName);
554     } //localInfos
555
} //licences
556
} //binBundles
557

558     Reporter.stopInfo("Bundle '" + bundleName + "' deleted (plus its potential licence file)");
559   }
560   
561   
562   /**
563    * Creates bundle (in its installed form) from the set of components from TR.
564    * The content of parameters vary according to the type of created bundle.
565    * <ul>
566    * <li>For user bundle: bundleName must be filled according to the user-bundle name specification, components and subsomponents - no restriction
567    * <li>For single-component bundle: bundleName must be empty, components must contain one component, subcomponents must be false
568    * <li>For complete-component bundle: bundleName must be empty, components must contain one component, subcomponents must be true
569    * </ul>
570    *
571    * @param bundleName name of bundle; empty for single-component of complete-component bundle
572    * @param components array of "base" components; must containt one component for single-component of complete-component bundle
573    * @param subcomponents if true, also subcomponents of "base" components will be included in the bundle
574    * @return name of created bundle
575    */

576   public String JavaDoc createBundle(String JavaDoc bundleName, ComponentInfo[] components, boolean subcomponents) throws CoreException
577   {
578     //test parameters
579
if (components == null || components.length == 0 ||
580         bundleName.length() == 0 && components.length > 1 )
581     {
582       throw new CoreException("Creation of bundle '" + bundleName + "' failed: Invalid parameters");
583     }
584     
585     boolean componentBundle = false;
586     
587     if (bundleName.length() == 0)
588     {
589       componentBundle = true;
590       bundleName = BundleInfo.makeComponentBundleName(components[0].getName(), components[0].getImplementationVersion(), subcomponents);
591     }
592     
593     Reporter.startInfo("Creating bundle '" + bundleName + "'");
594    
595     BundleInfo bundleInfo = new BundleInfo();
596     try
597     {
598       bundleInfo.fromBundleName(bundleName);
599     }
600     catch (BundleInfo.InvalidBundleNameException e)
601     {
602       throw new CoreException("Creation of bundle '" + bundleName + "' failed: Invalid name of bundle", e);
603     }
604     
605     if (componentBundle != bundleInfo.isComponent())
606     {
607       throw new CoreException("Creation of bundle '" + bundleName + "' failed: Invalid parameters");
608     }
609
610     //get description of components from repository
611
BundleImpl bundle = null;
612     try
613     {
614       bundle = (BundleImpl) tr.getBundle(components, null, subcomponents);
615     }
616     catch (TRException e)
617     {
618       new CoreException("Creation of bundle '" + bundleName + "' failed while getting information about components from TR", e);
619     }
620
621     BundleContents installedBundleContents = rep.getInstalledBundleContents();
622     LocalInfos localInfos = rep.getLocalInfos();
623
624     synchronized (installedBundleContents) {
625     synchronized (localInfos)
626     {
627       if (isBundleInstalled(bundleName))
628       {
629         throw new CoreException("Creation of bundle '" + bundleName + "' failed: Bundle is already installed");
630       }
631       
632       //get local info and modify it (it shouldn't exist, but we are prepared)
633
LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
634       if (localInfo != null)
635       {
636         if (localInfo.areShareClientModes()) new CoreException("Creation of bundle '" + bundleName + "' failed: Share client active for bundle of that name");
637         localInfo.setInstalled(true);
638         localInfo.saveToStorage();
639       }
640       else
641       {
642         localInfos.addLocalInfo(bundleName, new Licence(), LocalInfo.STATE_INSTALLED, null, null, false, "");
643       }
644       
645       //get installed bundle and modify it (if it exists, it is an incosistence of repository, but be can handle it)
646
//REMARK: I am not sure, whether objects components returned by TR are "local" (copies only for me
647
//or "global" - also someone else can have them - therefore i rather make copies
648
installedBundleContents.deleteBundleContent(bundleName); //delete it preventively
649

650       ComponentInfo[] bundleComponents = bundle.getComponents();
651       ComponentInfoImpl[] myComponents = new ComponentInfoImpl[bundleComponents.length];
652       for (int i = 0; i < bundleComponents.length; i++)
653       {
654         myComponents[i] = new ComponentInfoImpl(bundleComponents[i].getName(), bundleComponents[i].getImplementationVersion());
655       }
656       
657       installedBundleContents.addBundleContent(bundleName, myComponents);
658       
659     } //localInfos
660
} //installedBundleContents
661

662     bundle = null;
663     
664     Reporter.stopInfo("Bundle '" + bundleName + "' created");
665     return bundleName;
666   }
667   
668   /**
669    * Creates user bundle (in its installed form) from the set of components from TR.
670    *
671    * @param bundleName name of bundle - according to the user-bundle name specification
672    * @param components array of "base" components
673    * @param subcomponents if true, also subcomponents of "base" components will be included in the bundle
674    */

675   public void createUserBundle(String JavaDoc bundleName, ComponentInfo[] components, boolean subcomponents) throws CoreException
676   {
677     if (bundleName.length() == 0) throw new CoreException("Creation of user bundle failed: Empty name of user bundle");
678     createBundle(bundleName, components, subcomponents);
679   }
680   
681   /**
682    * Creates single-component bundle (in its installed form) from the component from TR.
683    * The bundle will be named by the component and will consist only of this component
684    *
685    * @param component component to create bundle from
686    * @return name of created bundle
687    */

688   public String JavaDoc createSingleComponentBundle(ComponentInfo component) throws CoreException
689   {
690     ComponentInfo[] components = new ComponentInfo[1];
691     components[0] = component;
692     return createBundle("", components, false);
693   }
694
695   /**
696    * Creates complete-component bundle (in its installed form) from the set of components from TR.
697    * The bundle will be named by the component (plus complete-component flag)
698    * and will consist of this component and all its subcomponents.
699    *
700    * @param component component to create bundle from
701    * @return name of created bundle
702    */

703   public String JavaDoc createCompleteComponentBundle(ComponentInfo component) throws CoreException
704   {
705     ComponentInfo[] components = new ComponentInfo[1];
706     components[0] = component;
707     return createBundle("", components, true);
708   }
709
710   /**
711    * Creates BundleData version of bundle consisting of component from TR (and its subcomponents).
712    * <p>
713    * Only for internal use of SOFAnet!!!!!
714    * The exception can be thrown only when an error in TR occurs or BundleData cannot be created.
715    * When component is not present in TR, null is returned.
716    *
717    * @param component description of component
718    * @param subcomponents if true, also subcomponents of component will be included in the bundle
719    * @return if component is present in TR: BundleData with bundle, null otherwise
720    */

721   BundleData createBundleFromTR(ComponentInfo component, boolean subcomponents) throws CoreException
722   {
723     //get description of components from repository
724
BundleImpl listBundle = null;
725     try
726     {
727       listBundle = (BundleImpl) tr.list();
728     }
729     catch (TRException e)
730     {
731       new CoreException("Creation of bundle of component '" + component.getName() + "[" + component.getImplementationVersion() + "]' failed while listing TR", e);
732     }
733
734     if (!listBundle.contains(component)) return null;
735     
736     
737     //get bundle from repository
738
BundleImpl bundle = null;
739     ComponentInfo[] components = new ComponentInfo[1];
740     components[0] = component;
741     try
742     {
743       bundle = (BundleImpl) tr.getBundle(null, components, subcomponents);
744     }
745     catch (TRException e)
746     {
747       new CoreException("Creation of bundle of component '" + component.getName() + "[" + component.getImplementationVersion() + "]' failed while getting component from TR", e);
748     }
749
750     //create file for bundleData
751
File tempFile = new File(BundleData.generateFilename());
752
753     try
754     {
755       FileOutputStream os = new FileOutputStream(tempFile);
756       bundle._write(os);
757       os.close();
758     }
759     catch (Exception JavaDoc e)
760     {
761       bundle = null;
762       new CoreException("Creation of bundle of component '" + component.getName() + "[" + component.getImplementationVersion() + "]' failed while creating BundleData", e);
763     }
764
765     bundle = null;
766
767     return new BundleData(tempFile, false);
768   }
769
770
771   /**
772    * Test presence of component (and its subcomponents) in TR.
773    * <p>
774    * Only for internal use of SOFAnet!!!!!
775    *
776    * @param component description of component
777    * @param subcomponents if true, also subcomponents of component will be tested
778    * @return true if component is present in TR, false otherwise
779    */

780   boolean testComponentPresenceInTR(ComponentInfo component, boolean subcomponents)
781   {
782     return tr.containsComponent(component, subcomponents);
783   }
784   
785   /**
786    * List components present in TR
787    * <p>
788    * Only for internal use of SOFAnet!!!!!
789    * @return array of components present in TR
790    */

791   ComponentInfo[] listComponentsPresentInTR()
792   {
793     return tr.list().getComponents();
794   }
795   
796   /**
797    * Notifies SOFAnet that the component (that exists in TR) is to be used by SOFA runtime.
798    * The caller is also informed whether it is allowed to use component (it has valid licence etc.)
799    * Every successfull call (use allowed) of this function must by accompanied by call of releaseComponent
800    * <p>
801    * Return codes:
802    * <ul>
803    * <li> 0 : use allowed - everything ok, component found
804    * <li> 1 : use allowed - component not found (is not contained in the bundle)
805    * <li> 2 : use not allowed - component found as part of a bundle, but the bundle is not installed (incosistence of SOFAnet repository)
806    * <li> 3 : use not allowed - component found as part of a bundle, but the bundle's licence disallows loading
807    * </ul>
808    *
809    * @param componentFullName full name of component(implementation) in form name[version]
810    * @return see return codes above
811    */

812   public int acquireComponent(String JavaDoc componentFullName)
813   {
814     String JavaDoc bundleName;
815     boolean shareManager = false;
816     NodeNameList shareClients = null;
817     
818     BundleContents installedBundleContents = rep.getInstalledBundleContents();
819     CompBundleMap compBundleMap = installedBundleContents.getCompBundleMap();
820     LocalInfos localInfos = rep.getLocalInfos();
821     
822     boolean secondRound = false;
823     for (;;)
824     {
825       synchronized (installedBundleContents) {
826       synchronized (localInfos)
827       {
828         //find bundle which the comonent belongs to
829
bundleName = compBundleMap.findBundle(componentFullName);
830         if (bundleName == null)
831         {
832           Reporter.info("Load of component '" + componentFullName + "' allowed (no bundle info)");
833           return 1;
834         }
835
836         //get LocalInfo of the bundle
837
LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
838         if (localInfo == null || !localInfo.isInstalled())
839         {
840           Reporter.warning("Load of component '" + componentFullName + "' from bundle '" + bundleName + "' PROHIBITED: The bundle int not installed");
841           return 3;
842         }
843
844         //if the bundle is already in memory, just increase counter
845
if (localInfo.isInMemory())
846         {
847           localInfo.increaseInMemoryCounter();
848           Reporter.info("Load of component '" + componentFullName + "' from bundle '" + bundleName + "' allowed (bundle already in memory)");
849           return 0;
850         }
851
852         //bundle is not in the memory yet, check licence
853

854         Licence licence = localInfo.getLicence();
855         //is licence valid?
856
if (!licence.isValid())
857         {
858           Reporter.warning("Load of component '" + componentFullName + "' from bundle '" + bundleName + "' PROHIBITED: Licence is not valid (expired)");
859           return 3;
860         }
861
862         //can we grant licence immediatelly?
863
if (!licence.withCopies() || licence.getNumberOfCopies() > 0)
864         {
865           if (licence.withCopies()) licence.decreaseNumberOfCopies(1);
866           localInfo.setInMemoryCounter(1);
867           localInfo.saveToStorage();
868           Reporter.info("Load of component '" + componentFullName + "' from bundle '" + bundleName + "' allowed (bundle loaded to memory)");
869           return 0;
870         }
871
872         //we have licence with copies but don't have free licence copy to use
873

874         if (!secondRound && licence.getType() == Licence.TYPE_ACTIVE && ((localInfo.isShareManager() && localInfo.getSMClients().getList().size() > 0) || localInfo.isShareClient()))
875         {
876           //this is our last chance how to obtain licence, but we will have to ask other nodes
877
if (localInfo.isShareManager())
878           {
879             shareManager = true;
880             shareClients = (NodeNameList)localInfo.getSMClients().clone();
881           }
882           else
883           {
884             shareManager = false;
885           }
886         }
887         else
888         {
889           //no chance to get licence
890
Reporter.warning("Load of component '" + componentFullName + "' from bundle '" + bundleName + "' PROHIBITED: Licence copy not available");
891           return 3;
892         }
893
894       } //localInfos
895
} //installedBundleContents
896

897
898       //now we know we have licence with active copies and there is sharing active
899
if (shareManager)
900       {
901         //we are the share manager of the bundle
902

903         IOParams ioParams = new IOParams();
904         ioParams.setBundleName(bundleName);
905         ioParams.setLicenceOnly(true);
906
907         shareOps.makeShareClientsReturnLicence(ioParams, bundleName, null, shareClients, null, "Returning of licence to share manager for bundle");
908
909         int errCode = ioParams.getErrCode();
910
911         if (errCode == 2)
912         {
913           Reporter.warning("Load of component '" + componentFullName + "' from bundle '" + bundleName + "' PROHIBITED: Licence copy not available");
914           return 3;
915         }
916
917         if (errCode != 0)
918         {
919           Reporter.error("Load of component '" + componentFullName + "' from bundle '" + bundleName + "' PROHIBITED: Incosistent state of share manager");
920           return 3;
921         }
922
923       }
924       else
925       {
926         //we are the share client of the bundle
927

928         try
929         {
930           shareOps.acquireSharedBundleLicence(bundleName);
931         }
932         catch (CoreException e)
933         {
934           Reporter.error(e);
935           Reporter.warning("Load of component '" + componentFullName + "' from bundle '" + bundleName + "' PROHIBITED: Acquisition of licence from share manager failed");
936           return 3;
937         }
938       }
939       
940       secondRound = true;
941     }
942   }
943   
944   /**
945    * Notifies SOFAnet that the component is to be released by SOFA runtime.
946    * <p>
947    * Return codes:
948    * <ul>
949    * <li> 0 : ok
950    * <li> 1 : incosistence of SOFAnet repository
951    * </ul>
952    *
953    * @param componentFullName full name of component(implementation) in form name[version]
954    * @return see return codes above
955    */

956   public int releaseComponent(String JavaDoc componentFullName)
957   {
958     BundleContents installedBundleContents = rep.getInstalledBundleContents();
959     CompBundleMap compBundleMap = installedBundleContents.getCompBundleMap();
960     LocalInfos localInfos = rep.getLocalInfos();
961     
962     synchronized (installedBundleContents) {
963     synchronized (localInfos)
964     {
965       //find bundle which the comonent belongs to
966
String JavaDoc bundleName = compBundleMap.findBundle(componentFullName);
967       if (bundleName == null)
968       {
969         Reporter.info("Component '" + componentFullName + "' released (no bundle info)");
970         return 0;
971       }
972
973       //get LocalInfo of the bundle
974
LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
975       if (localInfo == null || !localInfo.isInstalled() || !localInfo.isInMemory())
976       {
977         Reporter.error("Component '" + componentFullName + "' from bundle '" + bundleName + "' released, but SOFAnet repository in incosistent state");
978         return 1;
979       }
980
981       localInfo.decreaseInMemoryCounter();
982       if (!localInfo.isInMemory())
983       {
984         //the bundle is release from memory, return licence
985
Licence licence = localInfo.getLicence();
986         if (licence.withCopies()) licence.increaseNumberOfCopies(1);
987         localInfo.saveToStorage();
988         Reporter.info("Component '" + componentFullName + "' from bundle '" + bundleName + "' released (bundle released from memory)");
989       }
990       else
991       {
992         Reporter.info("Component '" + componentFullName + "' from bundle '" + bundleName + "' released (bundle remains in memory)");
993       }
994       
995       return 0;
996       
997     } //localInfos
998
} //installedBundleContents
999
}
1000  
1001  /**
1002   * Tries to provide ("download", "install",...) component that is missng in TR.
1003   * <p>
1004   * The fuction tries:
1005   * <ol>
1006   * <li>Sharing (share manager/share client)
1007   * <li>Binary bundles (component binary bundles)
1008   * <li>Bundle offers
1009   * <li>Search for the bundle
1010   * </ol>
1011   * <p>
1012   * Return codes (0 = OK, the others = error):
1013   * <ul>
1014   * <li> 0 : ok, component ready
1015   * <li> 1 : component marked as installed
1016   * <li> 2 : incosistence of SOFAnet repository
1017   * <li> 3 : installation of bundle failed
1018   * <li> 4 : cannot return shared bundle back
1019   * <li> 5 : local I/O error
1020   * <li> 6 : acquisition of shared bundle failed
1021   * <li> 7 : pull of bundle failed
1022   * <li> 8 : searching failed
1023   * <li> 9 : component not found
1024   * </ul>
1025   *
1026   * @param componentFullName full name of component(implementation) in form name[version]
1027   * @return see return codes above
1028   */

1029  public int obtainMissingComponent(String JavaDoc componentFullName) throws CoreException
1030  {
1031    Reporter.startInfo("Obtaining missing component '" + componentFullName + "' using SOFAnet");
1032
1033    BinBundles binBundles = rep.getBinBundles();
1034    LocalInfos localInfos = rep.getLocalInfos();
1035    BundleOffers bundleOffers = rep.getBundleOffers();
1036    CompBundleMap offersCompBundleMap = bundleOffers.getCompBundleMap();
1037    BinBundles shareClientCache = rep.getShareClientCache();
1038    BundleContents sharedBundleContents = rep.getSharedBundleContents();
1039    CompBundleMap sharedCompBundleMap = sharedBundleContents.getCompBundleMap();
1040    
1041    String JavaDoc bundleName = "";
1042    boolean returnLicenceAndBundleFromShareClient = false;
1043    NodeNameList shareClients = null;
1044    boolean acquireSharedBundle = false;
1045
1046    class InstallException extends Exception JavaDoc {}
1047    
1048    try
1049    {
1050      //first try sharing
1051
synchronized (binBundles) {
1052      synchronized (localInfos) {
1053      synchronized (shareClientCache) {
1054      synchronized (sharedBundleContents)
1055      {
1056        //we have to find name of bundle the component belongs to
1057
//we look at component-bundle map of sharedBundleContents, because every bundle with
1058
//active share manager or share client has the records here
1059

1060        bundleName = sharedCompBundleMap.findBundle(componentFullName);
1061        if (bundleName != null)
1062        {
1063          //get LocalInfo of the bundle
1064
LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
1065          if (localInfo == null || !localInfo.isShareManager() && !localInfo.isShareClient())
1066          {
1067            Reporter.error("Obtaining of component '" + componentFullName + "' of bundle '" + bundleName + "' failed: Missing share manager/share client state of the bundle");
1068            return 2;
1069          }
1070
1071          if (localInfo.isInstalled())
1072          {
1073            Reporter.error("Obtaining of component '" + componentFullName + "' of bundle '" + bundleName + "' failed: Bundle already marked as installed");
1074            return 1;
1075          }
1076
1077          if (localInfo.isShareManager())
1078          {
1079            //a) binary bundle is present: install (licence is solved by acquireComponent)
1080
//b) binary bundle is NOT present: return licence&bundle back from share client and install
1081

1082            //get binary bundle
1083
BundleInfo binBundle = binBundles.getBinBundle(bundleName);
1084            if (binBundle != null)
1085            {
1086              //install
1087
throw new InstallException();
1088            }
1089
1090            shareClients = (NodeNameList)localInfo.getSMClients().clone();
1091            if (shareClients.getList().size() > 0)
1092            {
1093              returnLicenceAndBundleFromShareClient = true;
1094            }
1095            else
1096            {
1097              Reporter.error("Obtaining of component '" + componentFullName + "' of bundle '" + bundleName + "' failed: No share client to return licence&bundle back to share manager");
1098              return 4;
1099            }
1100          }
1101          else
1102          {
1103            //share client
1104

1105            Licence licence = localInfo.getLicence();
1106            if (!licence.withCopies() || licence.getType() != Licence.TYPE_PHYSICAL || licence.getNumberOfCopies() > 0)
1107            {
1108              Reporter.error("Obtaining of component '" + componentFullName + "' of bundle '" + bundleName + "' failed: The share client of bundle active but wrong licence present");
1109              return 2;
1110            }
1111          
1112            acquireSharedBundle = true;
1113          }
1114        }
1115        else
1116        {
1117          //now we can try binary bundles
1118
Iterator it = binBundles.map.values().iterator();
1119          while (it.hasNext())
1120          {
1121            BundleInfo bundleInfo = (BundleInfo)it.next();
1122            
1123            if (bundleInfo.isComponentBundleOf(componentFullName))
1124            {
1125              //we found the binary bundle that is the component bundle of our missing component
1126
bundleName = bundleInfo.getName();
1127              throw new InstallException();
1128            }
1129          }
1130
1131          //other tries (bundle offers and search is later in the function
1132
}
1133      } //sharedBundleContents
1134
} //shareClientCache
1135
} //localInfos
1136
} //binBundles
1137

1138      if (returnLicenceAndBundleFromShareClient)
1139      {
1140        //we are share manager and we have to get back the licence and the bundle from the share client
1141

1142        IOParams ioParams = new IOParams();
1143        ioParams.setBundleName(bundleName);
1144        ioParams.setLicenceOnly(false);
1145
1146        shareOps.makeShareClientsReturnLicence(ioParams, bundleName, null, shareClients, null, "Returning of licence to share manager for bundle");
1147
1148        int errCode = ioParams.getErrCode();
1149
1150        if (errCode == 2)
1151        {
1152          Reporter.warning("Obtaining of component '" + componentFullName + "' of bundle '" + bundleName + "' failed: Cannot return licence&bundle back from share client");
1153          return 4;
1154        }
1155
1156        if (errCode != 0)
1157        {
1158          Reporter.error("Obtaining of component '" + componentFullName + "' of bundle '" + bundleName + "' failed: Incosistent state of share manager");
1159          return 2;
1160        }
1161
1162        ioParams.setBundleName(bundleName);
1163        ioParams.setNodeName(ioParams.getAddressNodeName());
1164        ioParams.setPriority(IOParams.PRIORITY_BLOCKING);
1165
1166        ioParams.setAddress(false);
1167        ioParams.setAddressNodeName("");
1168
1169        try
1170        {
1171          transport.acquireShared(ioParams);
1172        }
1173        catch (TransportException e)
1174        {
1175          Reporter.error("Obtaining of component '" + componentFullName + "' of bundle '" + bundleName + "' failed while calling acquireShared", e);
1176          return 4;
1177        }
1178
1179        if (ioParams.isAddress() || ioParams.getErrCode() != 0)
1180        {
1181          Reporter.error("Obtaining of component '" + componentFullName + "' of bundle '" + bundleName + "' failed: Unexpected result of acquireShared");
1182          return 4;
1183        }
1184        
1185        BundleData bundleData = ioParams.getBundleData();
1186
1187        //store bundleData to binary bundles
1188
synchronized (binBundles)
1189        {
1190          BundleInfo binBundle = binBundles.getBinBundle(bundleName);
1191          if (binBundle == null)
1192          {
1193            binBundle = binBundles.addBinBundle(bundleName);
1194            if (binBundle != null)
1195            {
1196              if (!bundleData.copyToFile(binBundle.getFile(), true))
1197              {
1198                bundleData.delete();
1199                binBundles.deleteBinBundle(bundleName);
1200                Reporter.error("Obtaining of component '" + componentFullName + "' of bundle '" + bundleName + "' failed while copying bundle to binary bundles");
1201                return 5;
1202              }
1203            }
1204            else
1205            {
1206              Reporter.warning("Obtaining of component '" + componentFullName + "' of bundle '" + bundleName + "' failed: Cannot add bundle to binary bundles, bundle already present");
1207            }
1208          }
1209          else
1210          {
1211            Reporter.warning("Obtaining of component '" + componentFullName + "' of bundle '" + bundleName + "' failed: Binary bundle already present");
1212          }
1213        } //binBundles
1214

1215        bundleData.delete();
1216        bundleData = null;
1217
1218        throw new InstallException();
1219      }
1220      
1221      
1222      if (acquireSharedBundle)
1223      {
1224        //share client; 0 physical licences
1225
boolean install = false;
1226        try
1227        {
1228          shareOps.acquireSharedBundle(bundleName, null, false);
1229          install = true;
1230        }
1231        catch (CoreException e)
1232        {
1233          if (e.getMessage().endsWith("Not a share manager or access not allowed"))
1234          {
1235            install = false;
1236            //the curent manager is probably not the share manager of the bundle any more;
1237
//stop the share client and continue as if no share client existed
1238
}
1239          else
1240          {
1241            Reporter.error("Obtaining of component '" + componentFullName + "' of bundle '" + bundleName + "': Acquisition of shared bundle failed", e);
1242            return 6;
1243          }
1244        }
1245
1246        if (install) throw new InstallException();
1247        else
1248        {
1249          //stop the share client
1250
try
1251          {
1252            shareOps.stopShareClientOfBundle(bundleName, true, false);
1253          }
1254          catch (CoreException e)
1255          {
1256            Reporter.error("Obtaining of component '" + componentFullName + "' of bundle '" + bundleName + "': Cannot stop obsolete share client", e);
1257            return 6;
1258          }
1259          
1260          acquireSharedBundle = false;
1261        }
1262      }
1263      
1264      
1265      //sharing and binary bundles has been already tried, now we continue by bundle offers
1266

1267      boolean tryPullBundle = false;
1268      String JavaDoc offeringNodeName = "";
1269      
1270      synchronized (binBundles) {
1271      synchronized (bundleOffers)
1272      {
1273        bundleName = offersCompBundleMap.findBundle(componentFullName);
1274        if (bundleName != null)
1275        {
1276          BundleOffer bundleOffer = bundleOffers.getBundleOffer(bundleName);
1277          
1278          if (bundleOffer == null)
1279          {
1280            Reporter.error("Obtaining of component '" + componentFullName + "' of bundle '" + bundleName + "' failed: Missing bundle offer (incosistency of component-bundle map of offers and offers themselves)");
1281            return 2;
1282          }
1283
1284          //we found the offer
1285

1286          //test wheter we don't have the bundle already
1287
BundleInfo binBundle = binBundles.getBinBundle(bundleName);
1288          if (binBundle != null)
1289          {
1290            //oh, we have the bundle
1291
throw new InstallException();
1292          }
1293          
1294          tryPullBundle = true;
1295          offeringNodeName = bundleOffer.getNodeName();
1296        }
1297      } //bundleOffers
1298
} //binBundles
1299

1300      if (tryPullBundle)
1301      {
1302        //we will try to pull the bundle from offering node
1303

1304        boolean canPull = false;
1305        try
1306        {
1307          canPull = netOps.testPull(bundleName, offeringNodeName, "");
1308        }
1309        catch (CoreException e)
1310        {
1311          Reporter.warning("Obtaining of component '" + componentFullName + "' of bundle '" + bundleName + "': Test of pull acceptance failed", e);
1312        }
1313        
1314        if (canPull)
1315        {
1316          try
1317          {
1318            netOps.synchroPullBundle(bundleName, offeringNodeName, "");
1319          }
1320          catch (CoreException e)
1321          {
1322            Reporter.error("Obtaining of component '" + componentFullName + "' of bundle '" + bundleName + "': Pull of bundle failed", e);
1323            return 6;
1324          }
1325          
1326          //ok, we downloaded bundle, now we can try to install it
1327
throw new InstallException();
1328        }
1329      }
1330      
1331      
1332      //now just searching remains
1333

1334      SearchReplyItem replyItem = null;
1335      try
1336      {
1337        replyItem = searchOps.searchForBundleWithComponent(componentFullName);
1338      }
1339      catch (CoreException e)
1340      {
1341        Reporter.error("Obtaining of component '" + componentFullName + "failed: Searching failed", e);
1342        return 8;
1343      }
1344      
1345      if (replyItem != null)
1346      {
1347        //we have found some share manager
1348

1349        bundleName = replyItem.getBundleName();
1350        
1351        try
1352        {
1353          shareOps.acquireSharedBundle(bundleName, replyItem.getNodeName(), true);
1354        }
1355        catch (CoreException e)
1356        {
1357          Reporter.error("Obtaining of component '" + componentFullName + "' of bundle '" + bundleName + "': Acquisition of shared bundle failed", e);
1358          return 6;
1359        }
1360        
1361        throw new InstallException();
1362      }
1363
1364      //component not found
1365

1366    }
1367    catch (InstallException ie)
1368    {
1369      //ok, we should install bundle
1370
try
1371      {
1372        installBundle(bundleName, true);
1373      }
1374      catch (CoreException e)
1375      {
1376        Reporter.error("Obtaining of component '" + componentFullName + "' of bundle '" + bundleName + "' failed", e);
1377        return 3;
1378      }
1379      
1380      Reporter.stopInfo("Component '" + componentFullName + "' found in bundle '" + bundleName + "'. Bundle obtained and installed.");
1381      return 0; //hurrah, we have succeeded
1382
}
1383
1384    Reporter.stopInfo("Missing component '" + componentFullName + "' not obtained.");
1385    return 9; //sorry, component not found
1386
}
1387}
1388
Popular Tags