KickJava   Java API By Example, From Geeks To Geeks.

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


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

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

23 public class ShareOps
24 {
25   private final boolean shareAllComponents;
26   private Repository rep;
27   private TransportInterface transport;
28   private LocalOps localOps;
29   
30   private List bundlesForAcquire;
31   
32   private static class NodeBundleDataPair
33   {
34     public String JavaDoc nodeName;
35     public BundleData bundleData;
36
37     NodeBundleDataPair()
38     {
39     }
40     
41     NodeBundleDataPair(String JavaDoc nodeName, BundleData bundleData)
42     {
43       this.nodeName = nodeName;
44       this.bundleData = bundleData;
45     }
46   }
47   
48   /** Creates a new instance of ShareOps */
49   public ShareOps()
50   {
51     String JavaDoc shareAllComponentsStr = System.getProperty(VMProperties.NET_SHARE_ALL_COMPONENTS, VMProperties.NET_SHARE_ALL_COMPONENTS_DEF).trim().toLowerCase();
52     shareAllComponents = shareAllComponentsStr.compareTo("1") == 0 || shareAllComponentsStr.compareTo("true") == 0;
53
54     bundlesForAcquire = Collections.synchronizedList(new LinkedList());
55   }
56
57   public void setRepository(Repository repository)
58   {
59     rep = repository;
60   }
61
62   public void setTransportInterface(TransportInterface transport)
63   {
64     this.transport = transport;
65   }
66   
67   public void setLocalOps(LocalOps localOps)
68   {
69     this.localOps = localOps;
70   }
71   
72   /**
73    * Returns bundle share status.
74    *
75    * @param bundleName name of bundle
76    * @return LocalInfo.STATE_NONE or LocalInfo.STATE_SHARE_CLIENT or LocalInfo.STATE_SHARE_MANAGER
77    */

78   public int bundleShareStatus(String JavaDoc bundleName)
79   {
80     LocalInfos localInfos = rep.getLocalInfos();
81     synchronized (localInfos)
82     {
83       LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
84       if (localInfo == null) return LocalInfo.STATE_NONE;
85       return localInfo.getState() & (LocalInfo.STATE_SHARE_CLIENT | LocalInfo.STATE_SHARE_MANAGER);
86     }
87   }
88   
89   /**
90    * Starts sharing of bundle.
91    *
92    * @param numberOfLicences positive integer or Licence.ALL_LICENCES - how many licences should be in local licence (in local info) and therefore available for sharing.
93    * @param shareGroups in which share groups should be the bundle visible (can be null == all groups)
94    * @param nodeFilter which nodes can access the bundle (can be null == all nodes)
95    * @param reshare true: if the sharing is already active, it is updated; false: error if sharing is already active
96    */

97   public void shareBundle(String JavaDoc bundleName, int numberOfLicences, ShareGroups shareGroups, NodeNameFilter nodeFilter, boolean equality, boolean reshare) throws CoreException
98   {
99     if (numberOfLicences == 0) throw new CoreException("Sharing of bundle '" + bundleName + "' failed: Invalid parameters - cannost share zero licence copies");
100
101     boolean updating = false;
102     Reporter.startInfo("Sharing of bundle '" + bundleName + "'");
103     
104     BundleInfo bundleInfo = new BundleInfo();
105     try
106     {
107       bundleInfo.fromBundleName(bundleName);
108     }
109     catch (BundleInfo.InvalidBundleNameException e)
110     {
111       throw new CoreException("Sharing of bundle '" + bundleName + "' failed: Invalid name of bundle", e);
112     }
113     
114     BinBundles binBundles = rep.getBinBundles();
115     BundleContents installedBundleContents = rep.getInstalledBundleContents();
116     LocalInfos localInfos = rep.getLocalInfos();
117     Licences licences = rep.getLicences();
118     BundleContents sharedBundleContents = rep.getSharedBundleContents();
119     
120     synchronized (binBundles) {
121     synchronized (installedBundleContents) {
122     synchronized (localInfos) {
123     synchronized (licences) {
124     synchronized (sharedBundleContents)
125     {
126       //get local info (if present) and check sharing states
127
LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
128       if (localInfo != null)
129       {
130         if (localInfo.areShareClientModes())
131         {
132           throw new CoreException("Sharing of bundle '" + bundleName + "' failed: Cannot share bundle provided by share client");
133         }
134         
135         if (localInfo.isShareManager())
136         {
137           if (!reshare)
138           {
139             throw new CoreException("Sharing of bundle '" + bundleName + "' failed: Tha bundle is already shared");
140           }
141           
142           updating = true;
143         }
144       }
145       
146       //get licence file (if present)
147
Licence lic = licences.getLicence(bundleName);
148
149       //get binary bundle
150
BundleInfo binBundle = binBundles.getBinBundle(bundleName);
151       
152       //-we don't need existence of BinBundle now, it can be created on request of sharing subsystem,
153
// bu we at least check, if BinBundle or installed version of bundle exists now
154
//-still it is possible to delete BinBundle and also uninstall bundle so that no
155
// copy of bundle remains on the system while sharing is active
156

157       if (binBundle == null && (localInfo == null || !localInfo.isInstalled()))
158       {
159         throw new CoreException("Sharing of bundle '" + bundleName + "' failed: Bundle is not present on the system in any form");
160       }
161       
162       BundleImpl bundle = null;
163       
164       if (binBundle != null && localInfo == null)
165       {
166         //decompress binary bundle to the temp and create BundleImpl structure - we will need it to create shareBundleContent
167
bundle = new BundleImpl();
168         try
169         {
170           bundle._read(new FileInputStream(binBundle.getFile()));
171         }
172         catch (IOException e)
173         {
174           throw new CoreException("Sharing of bundle '" + bundleName + "' failed while decompressing bundle", e);
175         }
176       }
177
178       //get licence and check validity
179
Licence licence = null;
180       if (localInfo != null)
181       {
182         licence = localInfo.getLicence();
183         if (!licence.isValid()) throw new CoreException("Sharing of bundle '" + bundleName + "' failed: Local licence is not valid (expired)");
184       }
185       
186       if (localInfo != null && localInfo.isInSharing() && licence.withCopies())
187       {
188         int sharedLicences = localInfo.getSMClients().getList().size();
189         
190         int localNum = licence.getNumberOfCopies();
191         int totalLocalNum = sharedLicences + localNum;
192         if (localInfo.isInMemory()) totalLocalNum++;
193         
194         if (numberOfLicences != Licence.ALL_LICENCES && totalLocalNum > numberOfLicences)
195         {
196           //we should return licence copies from local info to licence file
197
int returnNum = totalLocalNum - numberOfLicences;
198           if (returnNum > localNum)
199           {
200             //but there is not enough copies presently available in local info
201
throw new CoreException("Sharing of bundle '" + bundleName + "' failed: Cannot reduce number of local licence copies, too many copies in use");
202           }
203           else
204           {
205             if (lic != null && lic.withCopies())
206             {
207               lic.increaseNumberOfCopies(returnNum);
208               lic.saveToStorage();
209             }
210             
211             licence.decreaseNumberOfCopies(returnNum);
212           }
213         }
214         else if (numberOfLicences == Licence.ALL_LICENCES)
215         {
216           //we should acquire all available licence copies from licence file
217
if (lic != null)
218           {
219             if (!lic.isValid()) throw new CoreException("Sharing of bundle '" + bundleName + "' failed: Licence is not valid (expired)");
220             
221             if (lic.withCopies())
222             {
223               int num = lic.getNumberOfCopies();
224               lic.decreaseNumberOfCopies(num);
225               lic.saveToStorage();
226               
227               licence.increaseNumberOfCopies(num);
228             }
229             else
230             {
231               //licence file has unlimited copies, so transfer this also to local licence
232
licence.setNumberOfCopies(Licence.WITHOUT_COPIES);
233             }
234           }
235           else
236           {
237             //there are no restrictions by licence file (it doesn't exist)
238
licence.setNumberOfCopies(Licence.WITHOUT_COPIES);
239           }
240         }
241         else if (totalLocalNum < numberOfLicences)
242         {
243           //we should acquire licence copies from licence file
244
int acquireNum = numberOfLicences - totalLocalNum;
245           if (lic != null)
246           {
247             if (!lic.isValid()) throw new CoreException("Sharing of bundle '" + bundleName + "' failed: Licence is not valid (expired)");
248             
249             if (lic.withCopies())
250             {
251               if (lic.getNumberOfCopies() < acquireNum)
252               {
253                 //but there is not enough copies available in licence file
254
throw new CoreException("Sharing of bundle '" + bundleName + "' failed: Not enough licence copies available in licence file");
255               }
256
257               lic.decreaseNumberOfCopies(acquireNum);
258               lic.saveToStorage();
259             }
260           }
261           licence.increaseNumberOfCopies(acquireNum);
262         }
263         else
264         {
265           //no licence copies exchange between local info and licence file
266
}
267         
268         localInfo.setSMShareGroups(shareGroups);
269         localInfo.setSMNodeFilter(nodeFilter);
270         localInfo.setSMEquality(equality);
271         localInfo.saveToStorage();
272       }
273       else if (localInfo != null && localInfo.isInSharing() && !licence.withCopies())
274       {
275         if (numberOfLicences != Licence.ALL_LICENCES)
276         {
277           //following behaviour is questionable - we restrict local licence from "without copies"
278
//to concrete number of copies
279

280           //because sharing is active and share manager is not responsible to maintain list
281
//of all clients if licence is "without copies", therefore restricting licence to concrete
282
//number of copies can be applied only to future share clients
283

284           if (localInfo.isInMemory()) licence.setNumberOfCopies(numberOfLicences - 1);
285           else licence.setNumberOfCopies(numberOfLicences);
286         }
287           
288         localInfo.setSMShareGroups(shareGroups);
289         localInfo.setSMNodeFilter(nodeFilter);
290         localInfo.setSMEquality(equality);
291         localInfo.saveToStorage();
292       }
293       else
294       {
295         //sharing is surely not active
296

297         if (localInfo != null)
298         {
299           //-local info exists, local licence is also valid, licence != null
300
//-we also know:
301
// -there is no share client
302
// -bundle is installed
303
// -if local licence is with copies, there is one copy in it (including "in memory copy")
304
//-therefore we will never move licence copies from local licence to licence file
305

306           
307           if (licence.withCopies())
308           {
309             if (lic != null)
310             {
311               if (!lic.isValid()) throw new CoreException("Sharing of bundle '" + bundleName + "' failed: Licence is not valid (expired)");
312
313               if (lic.withCopies())
314               {
315                 //transfer requested number of copies from licence file
316
int licNum = lic.getNumberOfCopies();
317                 int licNumToTransfer;
318                 if (numberOfLicences == Licence.ALL_LICENCES) licNumToTransfer = licNum;
319                 else licNumToTransfer = numberOfLicences - 1; //there is already one copy in local licence
320

321                 if (licNumToTransfer > licNum) throw new CoreException("Sharing of bundle '" + bundleName + "' failed: Not enough licence copies available in licence file");
322
323                 licence.increaseNumberOfCopies(licNumToTransfer);
324
325                 lic.decreaseNumberOfCopies(licNumToTransfer);
326                 lic.saveToStorage();
327               }
328               else
329               {
330                 if (numberOfLicences != Licence.ALL_LICENCES)
331                 {
332                   //following behaviour is questionable - we restrict local licence from "without copies"
333
//to concrete number of copies; because sharing is not active yet, it should be ok
334
if (localInfo.isInMemory()) licence.setNumberOfCopies(numberOfLicences - 1);
335                   else licence.setNumberOfCopies(numberOfLicences);
336                 }
337                 else
338                 {
339                   //licence file is without copies, so we give "without copies" also to local licence
340
licence.setNumberOfCopies(Licence.WITHOUT_COPIES);
341                 }
342               }
343             }
344             else
345             {
346               //licence file doesn't exist - there is no limitation on tranfering copies to local licence
347
if (numberOfLicences == Licence.ALL_LICENCES) licence.setNumberOfCopies(Licence.WITHOUT_COPIES);
348               else licence.increaseNumberOfCopies(numberOfLicences - 1);
349             }
350           }
351           else
352           {
353             if (numberOfLicences != Licence.ALL_LICENCES)
354             {
355               //following behaviour is questionable - we restrict local licence from "without copies"
356
//to concrete number of copies; because sharing is not active yet, it should be ok
357
if (localInfo.isInMemory()) licence.setNumberOfCopies(numberOfLicences - 1);
358               else licence.setNumberOfCopies(numberOfLicences);
359             }
360             else
361             {
362               //we do nothing because local licence is not limited by number of copies
363
}
364           }
365           
366           localInfo.setShareManager(true);
367           localInfo.setSMShareGroups(shareGroups);
368           localInfo.setSMNodeFilter(nodeFilter);
369           localInfo.setSMClients(new NodeNameList());
370           localInfo.setSMEquality(equality);
371           localInfo.saveToStorage();
372         }
373         else
374         {
375           //we have to build local info
376

377           if (lic != null)
378           {
379             if (!lic.isValid()) throw new CoreException("Sharing of bundle '" + bundleName + "' failed: Licence is not valid (expired)");
380             
381             licence = (Licence)lic.clone();
382             
383             if (lic.withCopies())
384             {
385               //transfer requested number of copies from licence file
386
int licNum = lic.getNumberOfCopies();
387               int wantedNum = numberOfLicences;
388               if (wantedNum == Licence.ALL_LICENCES) wantedNum = licNum;
389               
390               if (wantedNum > licNum) throw new CoreException("Sharing of bundle '" + bundleName + "' failed: Not enough licence copies available in licence file");
391               
392               licence.setNumberOfCopies(wantedNum);
393
394               lic.decreaseNumberOfCopies(wantedNum);
395               lic.saveToStorage();
396             }
397             else
398             {
399               //licence file is without copies, so leave "without copies" also in local licence
400
}
401           }
402           else
403           {
404             //create empty local licence
405
licence = new Licence();
406           }
407           
408           //we have prepared local licence (licence != null), now we build local info itself
409
localInfo = localInfos.addLocalInfo(bundleName, licence, LocalInfo.STATE_SHARE_MANAGER, shareGroups, nodeFilter, equality, "");
410         }
411
412         //create shareBundleContent
413
BundleContent sharedBundleContent = sharedBundleContents.getBundleContent(bundleName);
414         if (sharedBundleContent != null) sharedBundleContents.deleteBundleContent(bundleName);
415         
416         BundleContent installedBundleContent = installedBundleContents.getBundleContent(bundleName);
417         if (installedBundleContent != null)
418         {
419           //use installed bundle
420
List components = installedBundleContent.getComponents();
421           sharedBundleContents.addBundleContent(bundleName, (ComponentInfo[])components.toArray(new ComponentInfoImpl[components.size()]));
422         }
423         else
424         {
425           //use decompressed bundle
426
sharedBundleContents.addBundleContent(bundleName, bundle.getComponents());
427         }
428       }
429       
430     } //sharedBundleContents
431
} //licences
432
} //localInfos
433
} //installedBundleContents
434
} //binBundles
435

436     if (updating) Reporter.stopInfo("Sharing of bundle '" + bundleName + "' updated");
437     else Reporter.stopInfo("Sharing of bundle '" + bundleName + "' started");
438   }
439     
440   /**
441    * Tests whether node (share client) can return shared bundle (it's licence) back to share manager.
442    *
443    * Synchronous (waits for completion).
444    * <p>
445    * Input:
446    * <ul>
447    * <li> bundleName
448    * <li> sourceNodeName &nbsp;&nbsp;<i> name of calling node (share manager)</i>
449    * </ul>
450    * <p>
451    * Output: none
452    *
453    * @param params Input data for the call
454    * @return true if shared bundle (or its licence can be returned to share manager)
455    */

456   public boolean canReturnSharedBundle(IOParams params) throws CoreException
457   {
458     String JavaDoc bundleName = params.getBundleName();
459     String JavaDoc nodeName = params.getSourceNodeName();
460     
461     BundleInfo bundleInfo = new BundleInfo();
462     try
463     {
464       bundleInfo.fromBundleName(bundleName);
465     }
466     catch (BundleInfo.InvalidBundleNameException e)
467     {
468       throw new CoreException("Return-shared-test of '" + bundleName + "' failed: Invalid name of bundle", e);
469     }
470     
471     LocalInfos localInfos = rep.getLocalInfos();
472     
473     synchronized (localInfos)
474     {
475       //get local info and check sharing state
476
LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
477       if (nodeName.compareTo(localInfo.getSCManager()) != 0) return false;
478       if (localInfo == null || !localInfo.isShareClient()) return false;
479       Licence licence = localInfo.getLicence();
480       if (licence.withCopies() && licence.getNumberOfCopies() == 0) return false;
481       
482       return true;
483     } //localInfos
484
}
485   
486   /**
487    * Return shared bundle (it's licence) back to share manager (and prepare binary bundle for acquire).
488    * <p>
489    * Synchronous (waits for completion).
490    * <p>
491    * Input:
492    * <ul>
493    * <li> bundleName
494    * <li> sourceNodeName
495    * <li> address
496    * <li> addressNodeName &nbsp;&nbsp;<i> (if address == true)</i>
497    * </ul>
498    * <p>
499    * Output (not in params!):
500    * <ul>
501    * <li> errCode
502    * <ul>
503    * <li> 0 == OK
504    * <li> 1 == Not a share client
505    * <li> 2 == Cannot return bundle(licence)
506    * <li> 3 == Cannot prepare for acquire (but licence is returned)
507    * </ul>
508    * </ul>
509    *
510    * @param params Input/Output data for the call
511    * @return see errCode
512    */

513   public int returnSharedBundle(IOParams params) throws CoreException
514   {
515     String JavaDoc bundleName = params.getBundleName();
516     String JavaDoc nodeName = params.getSourceNodeName();
517     
518     Reporter.startInfo("Returning (licence of) shared bundle '" + bundleName + "' (requesting node: '" + nodeName + "')");
519     
520     BundleInfo bundleInfo = new BundleInfo();
521     try
522     {
523       bundleInfo.fromBundleName(bundleName);
524     }
525     catch (BundleInfo.InvalidBundleNameException e)
526     {
527       throw new CoreException("Returning shared bundle '" + bundleName + "' failed: Invalid name of bundle", e);
528     }
529     
530     boolean removeBundle = false;
531     
532     BundleContents installedBundleContents = rep.getInstalledBundleContents();
533     LocalInfos localInfos = rep.getLocalInfos();
534     Licences licences = rep.getLicences();
535     BinBundles shareClientCache = rep.getShareClientCache();
536     
537     synchronized (installedBundleContents) { //because of localOps.uninstallBundle
538
synchronized (localInfos) {
539     synchronized (licences) //because of localOps.uninstallBundle
540
{
541       //get local info and check sharing state
542
LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
543       if (localInfo == null) return 1;
544       if (nodeName.compareTo(localInfo.getSCManager()) != 0) return 1;
545       if (localInfo.isSharePreClient()) return 2;
546       if (!localInfo.isShareClient()) return 1;
547       Licence licence = localInfo.getLicence();
548       
549       if (licence.withCopies())
550       {
551         int licNum = licence.getNumberOfCopies();
552         boolean physical = licence.getType() == Licence.TYPE_PHYSICAL;
553         
554         if (licNum == 0) return 2;
555       
556         if (physical && licNum == 1)
557         {
558           //there is only one "physical" licence - bundle cannot stay on this node
559
if (localInfo.isInstalled())
560           {
561             try
562             {
563               localOps.uninstallBundle(bundleName, true, false, false);
564             }
565             catch (CoreException e)
566             {
567               throw new CoreException("Returning shared bundle '" + bundleName + "' failed while uninstalling bundle", e);
568             }
569           }
570           
571           removeBundle = true;
572           
573           /* commented by Lada Sobr: we rather let share client, in the future another "acquireSharedBundle" can be done immediately on the share manager node
574           //local info should contain just share client state, that we remove
575           localInfos.deleteLocalInfo(bundleName);
576            */

577           
578           localInfo = localInfos.getLocalInfo(bundleName); //just to be sure after uninstall
579
if (localInfo != null)
580           {
581             licence = localInfo.getLicence();
582             if (licence.withCopies())
583             {
584               licence.decreaseNumberOfCopies(1);
585               localInfo.saveToStorage();
586             }
587           }
588         }
589         else
590         {
591           //we have "active" licence(s) or more than one "physical" licences, so just remove one
592
licence.decreaseNumberOfCopies(1);
593           localInfo.saveToStorage();
594         }
595       }
596       else
597       {
598         //no limitation of copies, we needn't to "change" state of this node
599
}
600     } //licences
601
} //localInfos
602
} //installedBundleContents
603

604     
605     //now we know the licence is removed from this node
606

607     int retCode = 0;
608
609     if (params.isAddress() || removeBundle)
610     {
611       synchronized (shareClientCache)
612       {
613         if (params.isAddress())
614         {
615           //we should prepare bundle for acquire
616
BundleInfo cachedBundle = shareClientCache.getBinBundle(bundleName);
617           if (cachedBundle != null)
618           {
619             BundleData bundleData = new BundleData(cachedBundle.getFile(), true);
620             if (bundleData.getFile() != null)
621             {
622               //ok, we have succesfully created bundleData, so remember it in bundlesForAcquire
623
bundlesForAcquire.add(new NodeBundleDataPair(params.getAddressNodeName(), bundleData));
624             }
625             else retCode = 3;
626           }
627           else retCode = 3;
628         }
629
630         if (removeBundle) shareClientCache.deleteBinBundle(bundleName);
631         
632       } //shareClientCache
633
}
634
635     if (retCode == 0)
636     {
637       if (params.isAddress()) Reporter.stopInfo("Licence of shared bundle '" + bundleName + "' returned successfully to node '" + nodeName + "', bundle is prepared for node '" + params.getAddressNodeName() + "'");
638       else Reporter.stopInfo("(licence of) shared bundle '" + bundleName + "' returned successfully to node '" + nodeName + "'");
639     }
640     else Reporter.stopInfo("Error occured while returning shared bundle '" + bundleName + "'");
641     
642     return retCode;
643   }
644   
645   /**
646    * Call returnShared (on behalf of share manager) on share client that requested it.
647    * <p>
648    * Synchronous (waits for completion).
649    * <p>
650    * Input:
651    * <ul>
652    * <li> bundleName
653    * <li> sourceNodeName &nbsp;&nbsp;<i> name of requesting node</i>
654    * </ul>
655    * <p>
656    * Output (not in params!):
657    * <ul>
658    * <li> errCode
659    * <ul>
660    * <li> 0 == OK
661    * <li> 1 == Not a share manager or access not allowed
662    * <li> 2 == returnShared failed
663    * </ul>
664    * </ul>
665    *
666    * @param params Input/Output data for the call
667    * @return see errCode
668    */

669   public int performManualReturnSharedBundle(IOParams params) throws CoreException
670   {
671     String JavaDoc bundleName = params.getBundleName();
672     String JavaDoc nodeName = params.getSourceNodeName();
673
674     Reporter.startInfo("Performing manual returnShared of '" + bundleName + "' on node '" + nodeName +"'");
675     
676     BundleInfo bundleInfo = new BundleInfo();
677     try
678     {
679       bundleInfo.fromBundleName(bundleName);
680     }
681     catch (BundleInfo.InvalidBundleNameException e)
682     {
683       throw new CoreException("Performing manual returnShared of '" + bundleName + "' failed: Invalid name of bundle", e);
684     }
685     
686     boolean wantBundle = false;
687     
688     BinBundles binBundles = rep.getBinBundles();
689     LocalInfos localInfos = rep.getLocalInfos();
690     
691     synchronized (binBundles) {
692     synchronized (localInfos)
693     {
694       LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
695       if (localInfo == null || !localInfo.isShareManager()) return 1;
696       NodeNameList clients = localInfo.getSMClients();
697       if (!clients.contains(nodeName)) return 1;
698
699       //we don't test node filter (it could change)
700

701       //do we need physical form of bundle? (in fact we don't need it in all situations, but we rather take it)
702
BundleInfo binBundle = binBundles.getBinBundle(bundleName);
703       if (binBundle == null) wantBundle = true;
704       
705     } //localInfos
706
} //binBundles
707

708     //perform returnShared itself
709
final String JavaDoc myNodeName = NodeInfo.getLocalNodeName();
710
711     IOParams ioParams = new IOParams();
712     ioParams.setBundleName(bundleName);
713     ioParams.setNodeName(nodeName);
714     if (wantBundle)
715     {
716       ioParams.setAddress(true);
717       ioParams.setAddressNodeName(myNodeName);
718     }
719     else
720     {
721       ioParams.setAddress(false);
722       ioParams.setAddressNodeName("");
723     }
724
725     int errCode = -1;
726     try
727     {
728       transport.returnShared(ioParams);
729       errCode = ioParams.getErrCode();
730     }
731     catch (TransportException e)
732     {
733       Reporter.error("Performing manual returnShared of '" + bundleName + "' failed while calling returnShared: ", e);
734       return 2;
735     }
736     
737     if (errCode == 1 || errCode == 2 || errCode > 3)
738     {
739       String JavaDoc errMsg;
740       switch (errCode)
741       {
742       case 1: errMsg = "Not a share client"; break;
743       case 2: errMsg = "Cannot return bundle(licence)"; break;
744       default: errMsg = "Unknown error"; break;
745       }
746       
747       Reporter.error("Performing manual returnShared of '" + bundleName + "' failed: returnShared's result:" + errMsg + " (error code " + errCode + ")");
748       return 2;
749     }
750
751     if (errCode == 3)
752     {
753       Reporter.error("Performing manual returnShared of '" + bundleName + "' partially failed: returnShared's result: Cannot prepare for acquire (but licence is returned) (error code 3)");
754     }
755     
756     //errCode == 0 : OK
757
//errCode == 3 : Licence returned, but physical bundle not prepared
758

759     BundleData bundleData = null;
760     
761     if (wantBundle && errCode == 0)
762     {
763       try
764       {
765         ioParams.setBundleName(bundleName);
766         ioParams.setNodeName(nodeName);
767         ioParams.setPriority(IOParams.PRIORITY_BLOCKING);
768         
769         transport.acquireShared(ioParams);
770         
771         if (ioParams.isAddress() || ioParams.getErrCode() != 0)
772         {
773           Reporter.error("Performing manual returnShared of '" + bundleName + "' partially failed: Unexpected result of acquireShared");
774         }
775         else bundleData = ioParams.getBundleData();
776       }
777       catch (TransportException e)
778       {
779         Reporter.error("Performing manual returnShared of '" + bundleName + "' partially failed while calling acquireShared", e);
780       }
781     }
782
783     //store bundle if needed
784
if (bundleData != null)
785     {
786       synchronized (binBundles)
787       {
788         BundleInfo binBundle = binBundles.getBinBundle(bundleName);
789         if (binBundle == null)
790         {
791           binBundle = binBundles.addBinBundle(bundleName);
792           if (binBundle != null)
793           {
794             if (!bundleData.copyToFile(binBundle.getFile(), true))
795             {
796               binBundles.deleteBinBundle(bundleName);
797               Reporter.error("Performing manual returnShared of '" + bundleName + "' partiallty failed while copying bundle to binary bundles");
798             }
799           }
800           else
801           {
802             Reporter.error("Performing manual returnShared of '" + bundleName + "' partially failed: Cannot add bundle to binary bundles");
803           }
804         }
805       } //binBundles
806

807       bundleData.delete();
808       bundleData = null;
809     }
810     
811     //change information of share manager
812
synchronized (localInfos)
813     {
814       LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
815       NodeNameList clients = localInfo.getSMClients();
816       if (localInfo != null && localInfo.isShareManager() && clients.contains(nodeName))
817       {
818         Licence licence = localInfo.getLicence();
819         if (licence.withCopies()) licence.increaseNumberOfCopies(1);
820
821         clients.remove(nodeName);
822         localInfo.saveToStorage();
823       }
824       else
825       {
826         Reporter.error("Performing manual returnShared of '" + bundleName + "' partially failed: Share manager's localInfo is in incosistent state");
827       }
828     } //localInfos
829

830     Reporter.stopInfo("Performing manual returnShared of '" + bundleName + "' on node '" + nodeName +"' completed");
831     
832     return 0;
833   }
834   
835   /**
836    * Tests whether node accepts acquire (sharing pull).
837    * <p>
838    * Synchronous (waits for completion).
839    * <p>
840    * Input:
841    * <ul>
842    * <li> bundleName
843    * <li> sourceNodeName &nbsp;&nbsp;<i> name of acquiring node</i>
844    * </ul>
845    * <p>
846    * Output: none
847    *
848    * @param params Input data for the call
849    * @return true if acquire is acceptable
850    */

851   public boolean isAcquisitionAcceptable(IOParams params) throws CoreException
852   {
853     String JavaDoc bundleName = params.getBundleName();
854     String JavaDoc nodeName = params.getSourceNodeName();
855     
856     BundleInfo bundleInfo = new BundleInfo();
857     try
858     {
859       bundleInfo.fromBundleName(bundleName);
860     }
861     catch (BundleInfo.InvalidBundleNameException e)
862     {
863       throw new CoreException("Test of acquisition acceptance of '" + bundleName + "' failed: Invalid name of bundle", e);
864     }
865
866     NodeNameList nodesForTest = null;
867     
868     LocalInfos localInfos = rep.getLocalInfos();
869     
870     synchronized (localInfos)
871     {
872       LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
873       if (localInfo == null || !localInfo.isShareManager()) return false;
874       NodeNameFilter nodeFilter = localInfo.getSMNodeFilter();
875       if (nodeFilter != null && !nodeFilter.pass(nodeName)) return false;
876       
877       Licence licence = localInfo.getLicence();
878       if (!licence.withCopies() || licence.getNumberOfCopies() > 0) return true;
879       
880       //now we know, that licence is with copy-number limitation and therefore we have to ask current share clients
881
//it must not be done in "synchronized" section
882
NodeNameList clients = localInfo.getSMClients();
883       if (clients == null) return false;
884       nodesForTest = (NodeNameList)clients.clone();
885     } //localInfos
886

887     ReturnSharedAcceptanceTester tester = new ReturnSharedAcceptanceTester(bundleName, nodesForTest, transport);
888     int willingNodeNum = tester.go();
889     return willingNodeNum != -1;
890   }
891   
892   /**
893    * Acquire bundle from sharing manager (or share client).
894    * <p>
895    * Synchronous (waits for completion).
896    * <p>
897    * Input:
898    * <ul>
899    * <li> bundleName
900    * <li> sourceNodeName &nbsp;&nbsp;<i> name of acquiring node</i>
901    * <li> licenceOnly
902    * </ul>
903    * <p>
904    * Output (on OK):
905    * <ul>
906    * <li> bundleName
907    * <li> address &nbsp;&nbsp;<i> (only if licenceOnly == false)</i>
908    * <li> bundleData &nbsp;&nbsp;<i> (only if licenceOnly == false && address == false)</i>
909    * <li> addressNodeName &nbsp;&nbsp;<i> (only if licenceOnly == false && address == true)</i>
910    * <li> licence &nbsp;&nbsp;<i> (only if asking share manager)</i>
911    * <li> errCode == 0
912    * </ul>
913    * <p>
914    * Output (on error):
915    * <ul>
916    * <li> errCode
917    * <ul>
918    * <li> 1 == Not a share manager or access not allowed
919    * <li> 2 == Licence not available
920    * <li> 3 == Data error (binary bundle not available) &nbsp;&nbsp;<i> (only if licenceOnly == false)</i>
921    * <li> 4 == Incosistent state of share manager
922    * </ul>
923    * </ul>
924    *
925    * @param params Input/Output data for the call
926    */

927   public void prepareBundleForAcquisition(IOParams params) throws CoreException
928   {
929     String JavaDoc bundleName = params.getBundleName();
930     String JavaDoc nodeName = params.getSourceNodeName();
931     boolean licenceOnly = params.isLicenceOnly();
932
933     if (licenceOnly) Reporter.startInfo("Preparing licence of shared bundle '" + bundleName + "' for acquisition");
934     else Reporter.startInfo("Preparing shared bundle '" + bundleName + "' for acquisition");
935     
936     BundleInfo bundleInfo = new BundleInfo();
937     try
938     {
939       bundleInfo.fromBundleName(bundleName);
940     }
941     catch (BundleInfo.InvalidBundleNameException e)
942     {
943       throw new CoreException("Preparation of bundle for acquisition '" + bundleName + "' failed: Invalid name of bundle", e);
944     }
945
946     //first test presence of nodeName in bundlesForAcquire
947
synchronized (bundlesForAcquire)
948     {
949       Iterator it = bundlesForAcquire.iterator();
950       while (it.hasNext())
951       {
952         NodeBundleDataPair nbdp = (NodeBundleDataPair)it.next();
953         if (nbdp.nodeName.compareTo(nodeName) == 0)
954         {
955           params.setAddress(false);
956           params.setBundleData(nbdp.bundleData);
957           params.setErrCode(0);
958           
959           bundlesForAcquire.remove(nbdp);
960           Reporter.stopInfo("Shared Bundle '" + bundleName + "' successfully acquired by node '" + nodeName + "'");
961           return;
962         }
963       }
964     }
965     
966     NodeNameList clients = null;
967     BundleData bundleData = null;
968     
969     //now we are sure, we are asked as share manager, not (former) share client
970

971     BinBundles binBundles = rep.getBinBundles();
972     BundleContents installedBundleContents = rep.getInstalledBundleContents();
973     LocalInfos localInfos = rep.getLocalInfos();
974
975     boolean tryCreateComponentBundle = false;
976     
977     //test presence of localInfo
978
//if not present and requested bundleName is name of component try to create bundle from repository (if it is allowed)
979
synchronized (localInfos)
980     {
981       LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
982       if (localInfo == null && shareAllComponents && !licenceOnly && bundleInfo.isComponent()) tryCreateComponentBundle = true;
983     } //localInfos
984

985     if (tryCreateComponentBundle)
986     {
987       ComponentInfoImpl component = new ComponentInfoImpl(bundleInfo.getShortName(), bundleInfo.getVersion());
988       boolean subcomponents = bundleInfo.isCompleteComponent();
989       
990       if (!localOps.testComponentPresenceInTR(component, subcomponents))
991       {
992         params.setErrCode(2);
993         return;
994       }
995       
996       try
997       {
998         bundleData = localOps.createBundleFromTR(component, subcomponents);
999       }
1000      catch (CoreException e)
1001      {
1002        Reporter.error("Preparation of bundle for acquisition '" + bundleName + "' failed while creating bundle from TR", e);
1003        params.setErrCode(3);
1004        return;
1005      }
1006      
1007      if (bundleData == null)
1008      {
1009        Reporter.error("Preparation of bundle for acquisition '" + bundleName + "' failed: Cannot create \"component\" bundle from TR");
1010        params.setErrCode(3);
1011        return;
1012      }
1013
1014      params.setLicence(new Licence()); //WE CREATE NOT LIMITED LICENCE!!!!
1015
params.setAddress(false);
1016      params.setBundleData(bundleData);
1017      params.setErrCode(0);
1018      return;
1019    }
1020    
1021    
1022    //consider regular bundles
1023
synchronized (binBundles) {
1024    synchronized (installedBundleContents) { //because of localOps.uninstallBundle
1025
synchronized (localInfos)
1026    {
1027      LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
1028      if (localInfo == null || !localInfo.isShareManager())
1029      {
1030        params.setErrCode(1);
1031        return;
1032      }
1033
1034      NodeNameFilter nodeFilter = localInfo.getSMNodeFilter();
1035      if (nodeFilter != null && !nodeFilter.pass(nodeName))
1036      {
1037        params.setErrCode(1);
1038        return;
1039      }
1040      
1041      boolean equality = localInfo.isSMEquality();
1042      Licence licence = localInfo.getLicence();
1043      Licence acqLicence = null;
1044      boolean decreasedLicNum = false;
1045      boolean physicalDeletion = false;
1046      
1047      if (licence.withCopies())
1048      {
1049        int numLic = licence.getNumberOfCopies();
1050        int numOtherLic = localInfo.getSMClients().getList().size();
1051        
1052        if (numLic + numOtherLic == 0) //no chance for licence
1053
{
1054          params.setErrCode(2);
1055          return;
1056        }
1057        
1058        if (equality)
1059        {
1060          //all licence copies can be moved from share manager
1061
}
1062        else
1063        {
1064          //at least one licence must stay at share manager
1065
if (!localInfo.isInMemory()) //remove one licence for "local" if it is not already used
1066
{
1067            numLic--;
1068            if (numLic < 0) numLic = 0; //just to be shure
1069
}
1070        }
1071
1072        if (numLic > 0)
1073        {
1074          //we can give copy from share manager
1075
acqLicence = (Licence)licence.clone();
1076          acqLicence.setNumberOfCopies(1);
1077          licence.decreaseNumberOfCopies(1);
1078          localInfo.getSMClients().add(nodeName);
1079          localInfo.saveToStorage();
1080          decreasedLicNum = true;
1081          
1082          if (licence.getType() == Licence.TYPE_PHYSICAL && equality && !localInfo.isInMemory()) physicalDeletion = true;
1083        }
1084        
1085      }
1086      else
1087      {
1088        acqLicence = (Licence)licence.clone();
1089      }
1090      
1091      
1092      //if we now have acqLicence, it means, that we can give licence from share manager;
1093
//otherwise we have to ask share clients for licence (and bundle)
1094

1095      if (acqLicence != null)
1096      {
1097        if (licenceOnly) //if we are asked just for licence, return it
1098
{
1099          if (physicalDeletion) //remove bundle if needed
1100
{
1101            try
1102            {
1103              if (localInfo.isInstalled()) localOps.uninstallBundle(bundleName, true, false, false);
1104              localOps.deleteBinaryBundle(bundleName);
1105            }
1106            catch (CoreException e)
1107            {
1108              Reporter.error("Preparation of bundle for acquisition '" + bundleName + "' failed while removing bundle", e);
1109            }
1110          }
1111          params.setLicence(acqLicence);
1112          params.setAddress(false);
1113          params.setBundleData(null);
1114          params.setErrCode(0);
1115          return;
1116        }
1117        
1118        //now we must prepare bundleData, physical bundle should be at the node
1119
BundleInfo binBundle = binBundles.getBinBundle(bundleName);
1120
1121        if (binBundle != null)
1122        {
1123          bundleData = new BundleData(binBundle.getFile(), true);
1124        }
1125        else if (localInfo.isInstalled())
1126        {
1127          bundleData = localOps.recreateBundleFromTR(bundleName);
1128        }
1129
1130        if (bundleData == null) //error
1131
{
1132          if (decreasedLicNum) //return licences back
1133
{
1134            licence.increaseNumberOfCopies(1);
1135            localInfo.saveToStorage();
1136          }
1137          params.setErrCode(3);
1138          return;
1139        }
1140
1141
1142        if (physicalDeletion) //remove bundle if needed
1143
{
1144          try
1145          {
1146            if (localInfo.isInstalled()) localOps.uninstallBundle(bundleName, true, false, false);
1147            localOps.deleteBinaryBundle(bundleName);
1148          }
1149          catch (CoreException e)
1150          {
1151            Reporter.error("Preparation of bundle for acquisition '" + bundleName + "' failed while removing bundle", e);
1152          }
1153        }
1154
1155        params.setLicence(acqLicence);
1156        params.setAddress(false);
1157        params.setBundleData(bundleData);
1158        params.setErrCode(0);
1159        return;
1160      }
1161      
1162      
1163      //prepare clients and if possible (and requested) also bundleData for other processing
1164

1165      clients = (NodeNameList)localInfo.getSMClients().clone();
1166      
1167      if (!licenceOnly)
1168      {
1169        BundleInfo binBundle = binBundles.getBinBundle(bundleName);
1170
1171        if (binBundle != null)
1172        {
1173          bundleData = new BundleData(binBundle.getFile(), true);
1174        }
1175        else if (localInfo.isInstalled())
1176        {
1177          bundleData = localOps.recreateBundleFromTR(bundleName);
1178        }
1179      }
1180      
1181    } //localInfos
1182
} //installedBundleContents
1183
} //binBundles
1184

1185    //if we get here:
1186
//1.we know, that nothing was changed (localInfo etc.) on this node and (except clients of share manager) will not change
1187
//2.we have to ask clients of share manager for licence + bundle
1188
//3.we have already prepared: clients, bundleData (if it is present on this node and was requested)
1189

1190    makeShareClientsReturnLicence(params, bundleName, nodeName, clients, bundleData, "Preparation for acquisition of bundle ");
1191    
1192    if (params.getErrCode() == 0)
1193    {
1194      if (licenceOnly) Reporter.stopInfo("Licence for shared bundle '" + bundleName + "' successfully acquired by node '" + nodeName + "'");
1195      else Reporter.stopInfo("Shared Bundle '" + bundleName + "' successfully acquired by node '" + nodeName + "'");
1196    }
1197    else
1198    {
1199      if (licenceOnly) Reporter.stopInfo("Error occured while preparing licence of shared bundle '" + bundleName + "' for acquisition by node '" + nodeName + "'");
1200      else Reporter.stopInfo("Error occured while preparing shared bundle '" + bundleName + "' for acquisition by node '" + nodeName + "'");
1201    }
1202  }
1203
1204  /**
1205   * Makes one of the share clients return licence and prepares IOParams structure for sending it to other client.
1206   * If nodeName == null, the function is called by share manager to return licence to it.
1207   * <p>
1208   * Input (in params):
1209   * <ul>
1210   * <li> bundleName
1211   * <li> licenceOnly &nbsp;&nbsp;<i> whether we request only licence or full bundle (can be provided by bundleData!)</i>
1212   * </ul>
1213   * <p>
1214   * Output (in params, on OK):
1215   * <ul>
1216   * <li> bundleName
1217   * <li> address &nbsp;&nbsp;<i> (only if licenceOnly == false)</i>
1218   * <li> bundleData &nbsp;&nbsp;<i> (only if licenceOnly == false && address == false)</i>
1219   * <li> addressNodeName &nbsp;&nbsp;<i> (only if licenceOnly == false && address == true)</i>
1220   * <li> licence &nbsp;&nbsp;<i> (not when returning licence to share manager)</i>
1221   * <li> errCode == 0
1222   * </ul>
1223   * <p>
1224   * Output (in params, on error):
1225   * <ul>
1226   * <li> errCode
1227   * <ul>
1228   * <li> 2 == Licence not available
1229   * <li> 4 == Incosistent state of share manager
1230   * </ul>
1231   * </ul>
1232   *
1233   * @param params Input/Output data for the call
1234   * @param bundleName name of bundle
1235   * @param nodeName name of asking node (the node that should acquire returned licence); null means this (local) node - licence&bundle is to be returned to share manager
1236   * @param client list of share clients to ask
1237   * @param bundleData if not null, that means the share manager has the bundle itself (deleted on error); if null share client should repare bundle if requested
1238   * @param errorText beggining of the text of error messages
1239   */

1240  void makeShareClientsReturnLicence(IOParams params, String JavaDoc bundleName, String JavaDoc nodeName, NodeNameList clients, BundleData bundleData, String JavaDoc errorText)
1241  {
1242    boolean shareManagerCalls = false;
1243    if (nodeName == null)
1244    {
1245      //share manager (this local node) is asking to return licence
1246
nodeName = NodeInfo.getLocalNodeName();
1247      shareManagerCalls = true;
1248    }
1249    
1250    LocalInfos localInfos = rep.getLocalInfos();
1251    
1252    for (int round = 0; round < 3; round++)
1253    {
1254      ReturnSharedAcceptanceTester tester = new ReturnSharedAcceptanceTester(bundleName, clients, transport);
1255      
1256      int result = tester.go();
1257      
1258      if (result == -1)
1259      {
1260        //there is no client, that could return licence
1261
if (bundleData != null) bundleData.delete();
1262        params.setErrCode(2);
1263        return;
1264      }
1265      
1266      String JavaDoc clientNodeName = (String JavaDoc)clients.getList().get(result);
1267      boolean wantBundle = bundleData == null && !params.isLicenceOnly();
1268
1269      IOParams ioParams = new IOParams();
1270      ioParams.setBundleName(bundleName);
1271      ioParams.setNodeName(clientNodeName);
1272      if (wantBundle)
1273      {
1274        ioParams.setAddress(true);
1275        ioParams.setAddressNodeName(nodeName);
1276      }
1277      else
1278      {
1279        ioParams.setAddress(false);
1280        ioParams.setAddressNodeName("");
1281      }
1282      
1283      int errCode = -1;
1284      try
1285      {
1286        transport.returnShared(ioParams);
1287        errCode = ioParams.getErrCode();
1288      }
1289      catch (TransportException e)
1290      {
1291        Reporter.error(errorText + " '" + bundleName + "' failed while returning shared bundle (node '" + clientNodeName + "') - ONE LICENCE PROBABLY LOST!!! ", e);
1292        errCode = -1;
1293      }
1294      
1295      if (errCode < -1 || errCode > 3)
1296      {
1297        Reporter.error(errorText + " '" + bundleName + "' failed: Unknown error code of returning shared bundle (node '" + clientNodeName + "'): " + errCode + " - ONE LICENCE PROBABLY LOST!!!");
1298        errCode = -1;
1299      }
1300
1301      //errCodes:
1302
// -1 == exception occured
1303
// 0 == OK
1304
// 1 == Not a share client
1305
// 2 == Cannot return bundle(licence)
1306
// 3 == Cannot prepare for acquire (but licence is returned)
1307

1308      switch (errCode)
1309      {
1310      case 1:
1311        Reporter.error(errorText + " '" + bundleName + "' failed while returning shared bundle (node '" + clientNodeName + "'): The node rejects to be share client, ONE LICENCE PROBABLY LOST!!!!");
1312        break;
1313      case 3:
1314        Reporter.error(errorText + " '" + bundleName + "' failed while returning shared bundle (node '" + clientNodeName + "'): The node cannot prepare physical bundle");
1315        break;
1316      }
1317      
1318      if (errCode != 2)
1319      {
1320        synchronized (localInfos)
1321        {
1322          LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
1323          if (localInfo == null || !localInfo.isShareManager())
1324          {
1325            //oh no, someone is working with our localInfo - we have too incosistent state :-(((
1326
if (errCode == 0 || errCode == 3)
1327            {
1328              Reporter.error(errorText + " '" + bundleName + "' failed: Incosistent LocalInfo, ONE LICENCE PROBABLY LOST!!!!");
1329            }
1330            else
1331            {
1332              Reporter.error(errorText + " '" + bundleName + "' failed: Incosistent LocalInfo");
1333            }
1334            if (bundleData != null) bundleData.delete();
1335            params.setErrCode(4);
1336            return;
1337          }
1338
1339          Licence licence = localInfo.getLicence();
1340          List clientList = localInfo.getSMClients().getList();
1341          Licence newLicence = null;
1342          
1343          switch (errCode)
1344          {
1345          case -1:
1346          case 1:
1347            //remove the clientNodeName from clients of share manager
1348
//remove the clientNodeName from "clients" - not to try it again
1349
clientList.remove(clientNodeName);
1350            localInfo.saveToStorage();
1351            clients.getList().remove(result);
1352            break;
1353          case 3:
1354            //remove the clientNodeName from clients of share manager
1355
//add return licence to localInfo
1356
//remove the clientNodeName from "clients" - not to try it again
1357
clientList.remove(clientNodeName);
1358            if (licence.withCopies()) licence.increaseNumberOfCopies(1);
1359            localInfo.saveToStorage();
1360            clients.getList().remove(result);
1361            break;
1362          case 0:
1363            //hurrah, we found the client node who accepted our request without any troubles
1364
//remove the clientNodeName from clients of share manager
1365
//add the nodeName to clients of share manager
1366

1367            clientList.remove(clientNodeName);
1368            if (shareManagerCalls)
1369            {
1370              //return licence back to share manager
1371
if (licence.withCopies()) licence.increaseNumberOfCopies(1);
1372              localInfo.saveToStorage();
1373
1374              params.setLicence(null);
1375            }
1376            else
1377            {
1378              clientList.add(nodeName);
1379              localInfo.saveToStorage();
1380              
1381              newLicence = (Licence)licence.clone();
1382              if (licence.withCopies()) newLicence.setNumberOfCopies(1);
1383
1384              params.setLicence(newLicence);
1385            }
1386            
1387
1388            if (params.isLicenceOnly())
1389            {
1390              params.setAddress(false);
1391              params.setAddressNodeName("");
1392              params.setBundleData(null);
1393            }
1394            else
1395            {
1396              if (wantBundle)
1397              {
1398                params.setAddress(true);
1399                params.setAddressNodeName(clientNodeName);
1400                params.setBundleData(null);
1401              }
1402              else
1403              {
1404                params.setAddress(false);
1405                params.setAddressNodeName("");
1406                params.setBundleData(bundleData);
1407              }
1408            }
1409            params.setErrCode(0);
1410            return;
1411          }
1412        } //localInfos
1413
}
1414      else
1415      {
1416        //just remove the clientNodeName from "clients" - not to try it again
1417
clients.getList().remove(result);
1418      }
1419    }
1420    
1421    //huh, we didn't find any client node that would return it's licence successfully
1422
if (bundleData != null) bundleData.delete();
1423    params.setErrCode(2);
1424  }
1425  
1426  /**
1427   * Stop sharing the bundle.
1428   *
1429   * @param bundleName name of bundle
1430   * @param recoverLicences if true, try to recover licences from share clients
1431   * @param force true: sharing is stopped even if share manager fails to recover all licence copies from clients (licence copies get lost); false: error if share manager fails to recover all licences
1432   */

1433  public void stopSharingBundle(String JavaDoc bundleName, boolean recoverLicences, boolean force) throws CoreException
1434  {
1435    Reporter.startInfo("Stopping sharing of bundle '" + bundleName + "'");
1436    
1437    BundleInfo bundleInfo = new BundleInfo();
1438    try
1439    {
1440      bundleInfo.fromBundleName(bundleName);
1441    }
1442    catch (BundleInfo.InvalidBundleNameException e)
1443    {
1444      throw new CoreException("Stopping of sharing of bundle '" + bundleName + "' failed: Invalid name of bundle", e);
1445    }
1446    
1447    LocalInfos localInfos = rep.getLocalInfos();
1448    Licences licences = rep.getLicences();
1449    BundleContents sharedBundleContents = rep.getSharedBundleContents();
1450
1451    //try to recover licences if we are requested to do it
1452
if (recoverLicences)
1453    {
1454      for (;;)
1455      {
1456        NodeNameList clients = null;
1457
1458        synchronized (localInfos)
1459        {
1460          //get local info (if present) and check sharing states
1461
LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
1462          if (localInfo != null && localInfo.isShareManager())
1463          {
1464            clients = (NodeNameList)localInfo.getSMClients().clone();
1465          }
1466        } //localInfos
1467

1468        if (clients == null || clients.getList().size() == 0) break;
1469        
1470        IOParams ioParams = new IOParams();
1471        
1472        Iterator it = clients.getList().iterator();
1473        while (it.hasNext())
1474        {
1475          String JavaDoc nodeName = (String JavaDoc)it.next();
1476          
1477          ioParams.setBundleName(bundleName);
1478          ioParams.setSourceNodeName(nodeName);
1479          
1480          try
1481          {
1482            performManualReturnSharedBundle(ioParams);
1483          }
1484          catch (CoreException e)
1485          {
1486            Reporter.error("Stopping of sharing of bundle '" + bundleName + "' failed while recovering licences from share clients", e);
1487          }
1488          
1489          //we don't check error codes
1490
}
1491        
1492        break;
1493      }
1494    }
1495    
1496    synchronized (localInfos) {
1497    synchronized (licences) {
1498    synchronized (sharedBundleContents)
1499    {
1500      //get local info (if present) and check sharing states
1501
LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
1502      if (localInfo == null || !localInfo.isShareManager())
1503      {
1504        throw new CoreException("Stopping of sharing of bundle '" + bundleName + "' failed: Bundle is not shared");
1505      }
1506      
1507      if (localInfo.getSMClients().getList().size() != 0 && !force)
1508      {
1509        throw new CoreException("Stopping of sharing of bundle '" + bundleName + "' failed: Cannot recover all licences");
1510      }
1511      
1512      localInfo.setShareManager(false);
1513      localInfo.setSMShareGroups(null);
1514      localInfo.setSMNodeFilter(null);
1515      localInfo.setSMClients(null);
1516      
1517      //delete content information of the shared bundle
1518
sharedBundleContents.deleteBundleContent(bundleName);
1519      
1520      
1521      //get licence file (if present)
1522
Licence lic = licences.getLicence(bundleName);
1523
1524      //get local licence
1525
Licence licence = localInfo.getLicence();
1526      
1527      //find out number of licences to return to licence file (if any)
1528
int numToReturn = Licence.WITHOUT_COPIES;
1529      if (licence.withCopies())
1530      {
1531        if (localInfo.isInstalled())
1532        {
1533          if (localInfo.isInMemory()) numToReturn = licence.getNumberOfCopies();
1534          else numToReturn = licence.getNumberOfCopies() - 1;
1535          licence.decreaseNumberOfCopies(numToReturn);
1536        }
1537        else
1538        {
1539          numToReturn = licence.getNumberOfCopies();
1540          licence.setNumberOfCopies(0); //just to be sure
1541
}
1542      }
1543      
1544      //return licences to licence file
1545
if (numToReturn != Licence.ALL_LICENCES && lic != null && lic.withCopies())
1546      {
1547        lic.increaseNumberOfCopies(numToReturn);
1548        lic.saveToStorage();
1549      }
1550      
1551      if (localInfo.getState() == LocalInfo.STATE_NONE) localInfos.deleteLocalInfo(bundleName);
1552      else localInfo.saveToStorage();
1553    
1554    } //sharedBundleContents
1555
} //licences
1556
} //localInfos
1557

1558    Reporter.stopInfo("Sharing of bundle '" + bundleName + "' stopped");
1559  }
1560
1561  
1562  /**
1563   * Acquires bundle from remote node's share manager (or share-client if we are relocated)
1564   * and stores it in share client cache.
1565   *
1566   * There are two possibilities (situations) how to call this function:
1567   * <ul>
1568   * <li>a) Bundle is not present on the node in any form. Requirements:
1569   * <ul>
1570   * <li>nodeName parameter specifies node with share manager (that should be tried)
1571   * <li>localInfo must not exist (bundle must not be installed, shared or in share-client mode).
1572   * </ul>
1573   * <li>b) Bundle has share client active, but budle was returned to share manager and physicaly removed from the node. Requirements:
1574   * <ul>
1575   * <li>nodeName is null; the share manager node will be taken from share client info
1576        <li>share client must be active for physical licences and 0 copies
1577   * <li>bundle muset not be installed
1578   * </ul>
1579   * </ul>
1580   * <p>
1581   * In b) if the acquisition of bundle failes, the share client of the bundle is stopped.
1582   *
1583   * @param bundleName name of bundle
1584   * @param nodeName name of sharing node ; can be null!!! see previous info
1585   */

1586  public void acquireSharedBundle(String JavaDoc bundleName, String JavaDoc nodeName, boolean tryNoShareClient) throws CoreException
1587  {
1588    if (nodeName != null) Reporter.startInfo("Acquiring shared bundle '" + bundleName + "' from node '" + nodeName + "'");
1589    else Reporter.startInfo("Acquiring shared bundle '" + bundleName + "'");
1590    
1591    BundleInfo bundleInfo = new BundleInfo();
1592    try
1593    {
1594      bundleInfo.fromBundleName(bundleName);
1595    }
1596    catch (BundleInfo.InvalidBundleNameException e)
1597    {
1598      throw new CoreException("Acquiring shared bundle '" + bundleName + "' failed: Invalid name of bundle", e);
1599    }
1600    
1601    if (nodeName != null)
1602    {
1603      NodeInfo nodeInfo = new NodeInfo();
1604      try
1605      {
1606        nodeInfo.setNodeName(nodeName);
1607      }
1608      catch (NodeInfo.InvalidNodeNameException e)
1609      {
1610        throw new CoreException("Acquiring shared bundle '" + bundleName + "' failed: Invalid name of SOFA node: " + nodeName, e);
1611      }
1612    }
1613    
1614    BinBundles binBundles = rep.getBinBundles();
1615    LocalInfos localInfos = rep.getLocalInfos();
1616    Licences licences = rep.getLicences();
1617    BinBundles shareClientCache = rep.getShareClientCache();
1618    BundleContents sharedBundleContents = rep.getSharedBundleContents();
1619    
1620    //test presence of local info
1621
synchronized (localInfos)
1622    {
1623      LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
1624      
1625      if (nodeName != null)
1626      {
1627        // call variant a) - "no share client"
1628
if (localInfo != null)
1629        {
1630          throw new CoreException("Acquiring shared bundle '" + bundleName + "' failed: Bundle is already present (locally - installed/shared)");
1631        }
1632
1633        localInfos.addLocalInfo(bundleName, new Licence(), LocalInfo.STATE_SHARE_PRECLIENT, null, null, false, "");
1634      }
1635      else
1636      {
1637        // call variant b) - "share client but no physical bundle"
1638
if (localInfo == null || localInfo.isInstalled() || !localInfo.isShareClient())
1639        {
1640          throw new CoreException("Acquiring shared bundle '" + bundleName + "' failed: Share client not active or bundle is already present (locally - installed/shared)");
1641        }
1642        Licence licence = localInfo.getLicence();
1643        if (!licence.withCopies() || licence.getType() != Licence.TYPE_PHYSICAL || licence.getNumberOfCopies() > 0)
1644        {
1645          throw new CoreException("Acquiring shared bundle '" + bundleName + "' failed: A physical licence is already present");
1646        }
1647        
1648        nodeName = localInfo.getSCManager();
1649        localInfo.setState(LocalInfo.STATE_SHARE_PRECLIENT);
1650        localInfo.saveToStorage();
1651      }
1652    } //localInfos
1653

1654    //if share client cache contains the bundle, delete it
1655
synchronized (shareClientCache)
1656    {
1657      BundleInfo cachedBundle = shareClientCache.getBinBundle(bundleName);
1658      if (cachedBundle != null) shareClientCache.deleteBinBundle(bundleName);
1659    } //shareClientCache
1660

1661    //contact remote node's share manager
1662
IOParams ioParams = new IOParams();
1663    ioParams.setBundleName(bundleName);
1664    ioParams.setPriority(IOParams.PRIORITY_BLOCKING);
1665    ioParams.setNodeName(nodeName);
1666    ioParams.setLicenceOnly(false);
1667
1668    try
1669    {
1670      transport.acquireShared(ioParams);
1671    }
1672    catch (TransportException e)
1673    {
1674      localInfos.deleteLocalInfo(bundleName); //remove share_preclient state
1675
throw new CoreException("Acquiring shared bundle '" + bundleName + "' failed while acquiring bundle at share manager", e);
1676    }
1677
1678    int errCode = ioParams.getErrCode();
1679    if (errCode != 0)
1680    {
1681      localInfos.deleteLocalInfo(bundleName); //remove share_preclient state
1682
switch (errCode)
1683      {
1684      case 1: throw new CoreException("Acquiring shared bundle '" + bundleName + "' failed: Share manager returns: Not a share manager or access not allowed"); //DO NOT CHANGE THIS STRING - IT IS USED TO RECOGNIZE THIS TYPE OF ERROR!!!!!
1685
case 2: throw new CoreException("Acquiring shared bundle '" + bundleName + "' failed: Share manager returns: Licence not available");
1686      case 3: throw new CoreException("Acquiring shared bundle '" + bundleName + "' failed: Share manager returns: Data error (binary bundle not available)");
1687      case 4: throw new CoreException("Acquiring shared bundle '" + bundleName + "' failed: Share manager returns: Incosistent state of share manager");
1688      default: throw new CoreException("Acquiring shared bundle '" + bundleName + "' failed: Transport layer failed");
1689      }
1690    }
1691    
1692    if (ioParams.isAddress())
1693    {
1694      //binary bundle must be acquired from another share client
1695

1696      IOParams ioParams2 = new IOParams();
1697      ioParams2.setBundleName(bundleName);
1698      ioParams2.setPriority(IOParams.PRIORITY_BLOCKING);
1699      ioParams2.setNodeName(ioParams.getAddressNodeName());
1700
1701      //contact share client
1702
try
1703      {
1704        transport.acquireShared(ioParams2);
1705      }
1706      catch (TransportException e)
1707      {
1708        localInfos.deleteLocalInfo(bundleName); //remove share_preclient state
1709
throw new CoreException("Acquiring shared bundle '" + bundleName + "' failed while acquiring binary bundle at share client (" + ioParams.getNodeName() + ")", e);
1710      }
1711
1712      int errCode2 = ioParams2.getErrCode();
1713      if (errCode2 != 0)
1714      {
1715        localInfos.deleteLocalInfo(bundleName); //remove share_preclient state
1716
switch (errCode2)
1717        {
1718        case 1: throw new CoreException("Acquiring shared bundle '" + bundleName + "' failed: Share client returns: Not a share manager or access not allowed");
1719        case 2: throw new CoreException("Acquiring shared bundle '" + bundleName + "' failed: Share client returns: Licence not available");
1720        case 3: throw new CoreException("Acquiring shared bundle '" + bundleName + "' failed: Share client returns: Data error (binary bundle not available)");
1721        case 4: throw new CoreException("Acquiring shared bundle '" + bundleName + "' failed: Share client returns: Incosistent state of share manager");
1722        default: throw new CoreException("Acquiring shared bundle '" + bundleName + "' failed: Transport layer failed");
1723        }
1724      }
1725      
1726      ioParams.setBundleData(ioParams2.getBundleData());
1727    }
1728    else
1729    {
1730      if (ioParams.getBundleData() == null) throw new CoreException("Acquiring shared bundle '" + bundleName + "' failed: acqureShared returned corrupted output (missing BundleData)");
1731    }
1732    
1733    //now we have in ioParams BundleData as well as licence
1734

1735    Licence licence = ioParams.getLicence();
1736    BundleData bundleData = ioParams.getBundleData();
1737    
1738    if (bundleData == null)
1739    {
1740      localInfos.deleteLocalInfo(bundleName); //remove share_preclient state
1741
throw new CoreException("Acquiring shared bundle '" + bundleName + "' failed: Binary version of bundle is not available");
1742    }
1743    
1744    boolean done = false;
1745    
1746    //if it is requested and possible, try to store bundle to binary bundles and not to run share client
1747
if (tryNoShareClient && (licence == null || !licence.withCopies()))
1748    {
1749      synchronized (binBundles) {
1750      synchronized (localInfos) {
1751      synchronized (licences)
1752      {
1753        //test presence of share_preclient state
1754
LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
1755        if (localInfo == null || localInfo.getState() != LocalInfo.STATE_SHARE_PRECLIENT)
1756        {
1757          bundleData.delete();
1758          throw new CoreException("Acquiring shared bundle '" + bundleName + "' failed: Incosistent state of LocalInfo - share preclient not found");
1759        }
1760        
1761        localInfos.deleteLocalInfo(bundleName); //remove share_preclient state
1762
localInfo = null;
1763        
1764        BundleInfo binBundle = binBundles.getBinBundle(bundleName);
1765        Licence lic = licences.getLicence(bundleName);
1766        
1767        if (binBundle == null && lic == null)
1768        {
1769          //copy bundle to binary bundles
1770
binBundle = binBundles.addBinBundle(bundleName);
1771          if (binBundle == null)
1772          {
1773            bundleData.delete();
1774            throw new CoreException("Acquiring shared bundle '" + bundleName + "' failed: Cannot add bundle to binary bundles");
1775          }
1776
1777          if (!bundleData.copyToFile(binBundle.getFile(), true))
1778          {
1779            bundleData.delete();
1780            binBundles.deleteBinBundle(bundleName);
1781            throw new CoreException("Acquiring shared bundle '" + bundleName + "' failed: Error occured while copying bundle to binary bundles");
1782          }
1783
1784          bundleData.delete();
1785          bundleData = null;
1786
1787          //add licence file
1788
if (licence != null)
1789          {
1790            lic = licences.addLicence(bundleName, licence.getType(), licence.getNumberOfCopies(),
1791                                      licence.getValidFrom(), licence.getValidTo(), licence.getText());
1792            if (lic == null)
1793            {
1794              binBundles.deleteBinBundle(bundleName);
1795              throw new CoreException("Acquiring shared bundle '" + bundleName + "' failed: Cannot add licence for bundle");
1796            }
1797          }
1798          
1799          done = true;
1800        }
1801      } //licences
1802
} //localInfos
1803
} //binBundles
1804
}
1805    
1806    if (!done)
1807    {
1808      //run share client
1809

1810      BundleImpl bundle = null;
1811      
1812      //decompress binary bundle to the temp and create BundleImpl structure - we will need it to create shareBundleContent
1813
bundle = new BundleImpl();
1814      try
1815      {
1816        bundle._read(new FileInputStream(bundleData.getFile()));
1817      }
1818      catch (IOException e)
1819      {
1820        throw new CoreException("Acquiring shared bundle '" + bundleName + "' failed while decompressing bundle", e);
1821      }
1822
1823      
1824      synchronized (localInfos) {
1825      synchronized (shareClientCache) {
1826      synchronized (sharedBundleContents)
1827      {
1828        //test presence of share_preclient state
1829
LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
1830        if (localInfo == null || localInfo.getState() != LocalInfo.STATE_SHARE_PRECLIENT)
1831        {
1832          bundleData.delete();
1833          throw new CoreException("Acquiring shared bundle '" + bundleName + "' failed: Incosistent state of LocalInfo - share preclient not found");
1834        }
1835        
1836        localInfos.deleteLocalInfo(bundleName); //remove share_preclient state
1837
localInfo = null;
1838
1839        //if share client cache contains the bundle, delete it (we must do it again)
1840
BundleInfo cachedBundle = shareClientCache.getBinBundle(bundleName);
1841        if (cachedBundle != null) shareClientCache.deleteBinBundle(bundleName);
1842        
1843        //copy bundle to share client cache
1844
cachedBundle = shareClientCache.addBinBundle(bundleName);
1845        if (cachedBundle == null)
1846        {
1847          bundleData.delete();
1848          throw new CoreException("Acquiring shared bundle '" + bundleName + "' failed: Cannot add bundle to share client cache");
1849        }
1850
1851        if (!bundleData.copyToFile(cachedBundle.getFile(), true))
1852        {
1853          bundleData.delete();
1854          shareClientCache.deleteBinBundle(bundleName);
1855          throw new CoreException("Acquiring shared bundle '" + bundleName + "' failed: Error occured while copying bundle to share client cache");
1856        }
1857        
1858        bundleData.delete();
1859        bundleData = null;
1860        
1861        //create local info
1862
localInfos.addLocalInfo(bundleName, licence, LocalInfo.STATE_SHARE_CLIENT, null, null, false, nodeName);
1863        
1864        
1865        //create shareBundleContent
1866
BundleContent sharedBundleContent = sharedBundleContents.getBundleContent(bundleName);
1867        if (sharedBundleContent != null) sharedBundleContents.deleteBundleContent(bundleName);
1868        sharedBundleContents.addBundleContent(bundleName, bundle.getComponents());
1869        
1870      } //sharedBundleContents
1871
} //shareClientCache
1872
} //localInfos
1873
}
1874    
1875    if (nodeName != null) Reporter.stopInfo("Shared bundle '" + bundleName + "' acquired from node '" + nodeName + "'");
1876    else Reporter.stopInfo("Shared bundle '" + bundleName + "' acquired");
1877  }
1878
1879
1880  /**
1881   * Acquires licence for bundle from remote node's share manager
1882   * <p>
1883   * For successfull call, share-client must be already running.
1884   *
1885   * @param bundleName name of bundle
1886   */

1887  public void acquireSharedBundleLicence(String JavaDoc bundleName) throws CoreException
1888  {
1889    Reporter.startInfo("Acquiring licence for shared bundle '" + bundleName + "'");
1890    
1891    BundleInfo bundleInfo = new BundleInfo();
1892    try
1893    {
1894      bundleInfo.fromBundleName(bundleName);
1895    }
1896    catch (BundleInfo.InvalidBundleNameException e)
1897    {
1898      throw new CoreException("Acquiring licence for shared bundle '" + bundleName + "' failed: Invalid name of bundle", e);
1899    }
1900
1901    String JavaDoc manager = "";
1902    
1903    LocalInfos localInfos = rep.getLocalInfos();
1904    
1905    //find out name of node with share manager
1906
synchronized (localInfos)
1907    {
1908      LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
1909      if (localInfo == null || !localInfo.isShareClient())
1910      {
1911        throw new CoreException("Acquiring licence for shared bundle '" + bundleName + "' failed: Bundle is not in share-client mode");
1912      }
1913      
1914      manager = localInfo.getSCManager();
1915    } //localInfos
1916

1917    if (manager.length() == 0)
1918    {
1919      throw new CoreException("Acquiring licence for shared bundle '" + bundleName + "' failed: Empty name of node with share manager");
1920    }
1921    
1922
1923    //contact remote node's share manager
1924
IOParams ioParams = new IOParams();
1925    ioParams.setBundleName(bundleName);
1926    ioParams.setPriority(IOParams.PRIORITY_BLOCKING);
1927    ioParams.setNodeName(manager);
1928    ioParams.setLicenceOnly(false);
1929
1930    try
1931    {
1932      transport.acquireShared(ioParams);
1933    }
1934    catch (TransportException e)
1935    {
1936      throw new CoreException("Acquiring licence for shared bundle '" + bundleName + "' failed while acquiring licence at share manager", e);
1937    }
1938
1939    int errCode = ioParams.getErrCode();
1940    if (errCode != 0)
1941    {
1942      switch (errCode)
1943      {
1944      case 1: throw new CoreException("Acquiring licence for shared bundle '" + bundleName + "' failed: Share manager returns: Not a share manager or access not allowed");
1945      case 2: throw new CoreException("Acquiring licence for shared bundle '" + bundleName + "' failed: Share manager returns: Licence not available");
1946      case 3: throw new CoreException("Acquiring licence for shared bundle '" + bundleName + "' failed: Share manager returns: Data error (binary bundle not available)");
1947      case 4: throw new CoreException("Acquiring licence for shared bundle '" + bundleName + "' failed: Share manager returns: Incosistent state of share manager");
1948      default: throw new CoreException("Acquiring licence for shared bundle '" + bundleName + "' failed: Transport layer failed");
1949      }
1950    }
1951    
1952    //store new licence file to localInfo
1953
synchronized (localInfos)
1954    {
1955      LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
1956      if (localInfo == null || !localInfo.isShareClient())
1957      {
1958        throw new CoreException("Acquiring licence for shared bundle '" + bundleName + "' failed: Bundle is not in share-client mode. ACQUIRED LICENCE IS LOST!!!!!!");
1959      }
1960      
1961      localInfo.setLicence(ioParams.getLicence());
1962    } //localInfos
1963

1964    Reporter.stopInfo("Licence for shared bundle '" + bundleName + "' acquired from node '" + manager + "'");
1965  }
1966
1967  /**
1968   * Returns missing bundle back to this node that is share manager.
1969   * <p>
1970   * The function is the equivalent of acquireSharedBundle(bundleName, null, false) for share manager.
1971   * For successfull call, bundle must be shared (the node must be the share manager of the bundle) and
1972   * bundle must be physically missing on the node (must not be installed or binary bundle present) -
1973   * in fact bundle must have licence of "physical type" and 0 copies present.
1974   *
1975   * @param bundleName name of bundle
1976   */

1977  public void makeShareClientsReturnBundle(String JavaDoc bundleName) throws CoreException
1978  {
1979    NodeNameList shareClients = null;
1980    
1981    BinBundles binBundles = rep.getBinBundles();
1982    LocalInfos localInfos = rep.getLocalInfos();
1983    
1984    //find out the state of bundle and clients of the share manager
1985
synchronized (localInfos)
1986    {
1987      LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
1988      
1989      if (localInfo == null || !localInfo.isShareManager())
1990      {
1991        throw new CoreException("Making share clients return bundle '" + bundleName + "' failed: Bundle is not shared (the node is not the Share manager of the bundle)");
1992      }
1993      
1994      shareClients = (NodeNameList)localInfo.getSMClients().clone();
1995      if (shareClients.getList().size() == 0)
1996      {
1997        throw new CoreException("Making share clients return bundle '" + bundleName + "' failed: No share client to return licence&bundle back to share manager");
1998      }
1999    } //localInfos
2000

2001    //get back the licence and the bundle from the share client
2002
IOParams ioParams = new IOParams();
2003    ioParams.setBundleName(bundleName);
2004    ioParams.setLicenceOnly(false);
2005
2006    makeShareClientsReturnLicence(ioParams, bundleName, null, shareClients, null, "Returning of licence to share manager for bundle");
2007
2008    int errCode = ioParams.getErrCode();
2009
2010    if (errCode == 2) throw new CoreException("Making share clients return bundle '" + bundleName + "' failed: Cannot return licence&bundle back from share client");
2011    if (errCode != 0) throw new CoreException("Making share clients return bundle '" + bundleName + "' failed: Incosistent state of share manager");
2012
2013    
2014    ioParams.setBundleName(bundleName);
2015    ioParams.setNodeName(ioParams.getAddressNodeName());
2016    ioParams.setPriority(IOParams.PRIORITY_BLOCKING);
2017
2018    ioParams.setAddress(false);
2019    ioParams.setAddressNodeName("");
2020
2021    try
2022    {
2023      transport.acquireShared(ioParams);
2024    }
2025    catch (TransportException e)
2026    {
2027      throw new CoreException("Making share clients return bundle '" + bundleName + "' failed while calling acquireShared", e);
2028    }
2029
2030    if (ioParams.isAddress() || ioParams.getErrCode() != 0)
2031    {
2032      throw new CoreException("Making share clients return bundle '" + bundleName + "' failed: Unexpected result of acquireShared");
2033    }
2034
2035    BundleData bundleData = ioParams.getBundleData();
2036
2037    //store bundleData to binary bundles
2038
synchronized (binBundles)
2039    {
2040      BundleInfo binBundle = binBundles.getBinBundle(bundleName);
2041      if (binBundle == null)
2042      {
2043        binBundle = binBundles.addBinBundle(bundleName);
2044        if (binBundle != null)
2045        {
2046          if (!bundleData.copyToFile(binBundle.getFile(), true))
2047          {
2048            bundleData.delete();
2049            binBundles.deleteBinBundle(bundleName);
2050            throw new CoreException("Making share clients return bundle '" + bundleName + "' failed while copying bundle to binary bundles");
2051          }
2052        }
2053        else
2054        {
2055          throw new CoreException("Making share clients return bundle '" + bundleName + "' failed: Cannot add bundle to binary bundles, bundle already present");
2056        }
2057      }
2058      else
2059      {
2060        throw new CoreException("Making share clients return bundle '" + bundleName + "' failed: Binary bundle already present");
2061      }
2062    } //binBundles
2063

2064    bundleData.delete();
2065    bundleData = null;
2066  }
2067  
2068  /**
2069   * Stop share client of the bundle.
2070   * <p>
2071   * For successfull call, bundle must not be installed
2072   *
2073   * @param bundleName name of bundle
2074   * @param returnLicence if true, try to return licence to share manager
2075   * @param force true: share client is stopped even if licence is not returned to share manager; false: error (and do not stop share client) if licence cannot be returned
2076   */

2077  public void stopShareClientOfBundle(String JavaDoc bundleName, boolean returnLicence, boolean force) throws CoreException
2078  {
2079    Reporter.startInfo("Stopping share client of bundle '" + bundleName + "'");
2080
2081    BundleInfo bundleInfo = new BundleInfo();
2082    try
2083    {
2084      bundleInfo.fromBundleName(bundleName);
2085    }
2086    catch (BundleInfo.InvalidBundleNameException e)
2087    {
2088      throw new CoreException("Stopping share client of bundle '" + bundleName + "' failed: Invalid name of bundle", e);
2089    }
2090    
2091    String JavaDoc manager;
2092    
2093    LocalInfos localInfos = rep.getLocalInfos();
2094    BinBundles shareClientCache = rep.getShareClientCache();
2095    BundleContents sharedBundleContents = rep.getSharedBundleContents();
2096    
2097    synchronized (localInfos)
2098    {
2099      LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
2100      if (localInfo == null || !localInfo.isShareClient())
2101      {
2102        throw new CoreException("Stopping share client of bundle '" + bundleName + "' failed: Bundle is not in share-client mode");
2103      }
2104
2105      if (localInfo.isInstalled())
2106      {
2107        throw new CoreException("Stopping share client of bundle '" + bundleName + "' failed: Bundle is installed");
2108      }
2109      
2110      Licence licence = localInfo.getLicence();
2111      
2112      if (!licence.withCopies() || licence.getNumberOfCopies() == 0 || !returnLicence)
2113      {
2114        //we can do everything now
2115

2116        if (licence.withCopies() && licence.getNumberOfCopies() > 0 && !returnLicence)
2117        {
2118          if (force) Reporter.error("Stopping share client of bundle '" + bundleName + "': Not returning licence to share manager - ONE LICENCE LOST!");
2119          else throw new CoreException("Stopping share client of bundle '" + bundleName + "' failed: The shared licence copies are still present (not returned to share manager)");
2120        }
2121        
2122        synchronized (shareClientCache) {
2123        synchronized (sharedBundleContents)
2124        {
2125          sharedBundleContents.deleteBundleContent(bundleName);
2126          shareClientCache.deleteBinBundle(bundleName);
2127        } //sharedBundleContents
2128
} //shareClientCache
2129

2130        localInfos.deleteLocalInfo(bundleName);
2131        
2132        Reporter.stopInfo("Share client of bundle " + bundleName + " successfully stopped");
2133        return;
2134      }
2135      
2136      manager = localInfo.getSCManager();
2137    } //localInfos
2138

2139    
2140    //now we know that we have to return licences to share manager first
2141

2142    IOParams ioParams = new IOParams();
2143    ioParams.setBundleName(bundleName);
2144    ioParams.setNodeName(manager);
2145
2146    try
2147    {
2148      transport.manualReturnShared(ioParams);
2149    }
2150    catch (TransportException e)
2151    {
2152      throw new CoreException("Stopping share client of bundle '" + bundleName + "' failed while acquiring licence at share manager", e);
2153    }
2154    
2155    int errCode = ioParams.getErrCode();
2156    if (errCode != 0)
2157    {
2158      switch (errCode)
2159      {
2160      case 1: throw new CoreException("Stopping share client of bundle '" + bundleName + "' failed: Share manager returns: Not a share manager or access not allowed");
2161      case 2: throw new CoreException("Stopping share client of bundle '" + bundleName + "' failed: Share manager returns: returnShared failed");
2162      default: throw new CoreException("Stopping share client of bundle '" + bundleName + "' failed: Transport layer failed");
2163      }
2164    }
2165
2166    //stop the share client
2167
synchronized (localInfos)
2168    {
2169      LocalInfo localInfo = localInfos.getLocalInfo(bundleName);
2170      if (localInfo != null && localInfo.isShareClient())
2171      {
2172        if (localInfo.isInstalled())
2173        {
2174          throw new CoreException("Stopping share client of bundle '" + bundleName + "' failed: Bundle is installed");
2175        }
2176        
2177        synchronized (shareClientCache) {
2178        synchronized (sharedBundleContents)
2179        {
2180          sharedBundleContents.deleteBundleContent(bundleName);
2181          shareClientCache.deleteBinBundle(bundleName);
2182        } //sharedBundleContents
2183
} //shareClientCache
2184

2185        localInfos.deleteLocalInfo(bundleName);
2186      }
2187    } //localInfos
2188

2189    Reporter.stopInfo("Share client of bundle '" + bundleName + "' successfully stopped");
2190  }
2191}
2192
Popular Tags