KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > update > internal > core > UpdateManagerUtils


1 /*******************************************************************************
2  * Copyright (c) 2005, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * Chris Aniszczyk (IBM Corp.) - Fixed NPE
11  *******************************************************************************/

12 package org.eclipse.update.internal.core;
13
14 import java.io.BufferedWriter JavaDoc;
15 import java.io.File JavaDoc;
16 import java.io.FileNotFoundException JavaDoc;
17 import java.io.FileOutputStream JavaDoc;
18 import java.io.IOException JavaDoc;
19 import java.io.InputStream JavaDoc;
20 import java.io.OutputStream JavaDoc;
21 import java.io.OutputStreamWriter JavaDoc;
22 import java.io.PrintWriter JavaDoc;
23 import java.io.UnsupportedEncodingException JavaDoc;
24 import java.net.MalformedURLException JavaDoc;
25 import java.net.URL JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.Arrays JavaDoc;
28 import java.util.Date JavaDoc;
29 import java.util.EmptyStackException JavaDoc;
30 import java.util.HashMap JavaDoc;
31 import java.util.List JavaDoc;
32 import java.util.Locale JavaDoc;
33 import java.util.Map JavaDoc;
34 import java.util.ResourceBundle JavaDoc;
35 import java.util.Stack JavaDoc;
36 import java.util.StringTokenizer JavaDoc;
37
38 import org.eclipse.core.runtime.Assert;
39 import org.eclipse.core.runtime.CoreException;
40 import org.eclipse.core.runtime.Platform;
41 import org.eclipse.osgi.util.NLS;
42 import org.eclipse.update.core.ContentReference;
43 import org.eclipse.update.core.IFeature;
44 import org.eclipse.update.core.IFeatureReference;
45 import org.eclipse.update.core.IImport;
46 import org.eclipse.update.core.IIncludedFeatureReference;
47 import org.eclipse.update.core.IPlatformEnvironment;
48 import org.eclipse.update.core.IPluginEntry;
49 import org.eclipse.update.core.InstallMonitor;
50 import org.eclipse.update.core.Site;
51 import org.eclipse.update.core.SiteManager;
52 import org.eclipse.update.core.Utilities;
53 import org.eclipse.update.core.model.InstallAbortedException;
54 import org.eclipse.update.internal.core.connection.ConnectionFactory;
55 import org.eclipse.update.internal.core.connection.IResponse;
56 import org.osgi.framework.Bundle;
57 import org.osgi.framework.Constants;
58 import org.osgi.service.packageadmin.PackageAdmin;
59
60 /**
61  *
62  */

63 public class UpdateManagerUtils {
64
65     private static boolean OS_UNIX = org.eclipse.osgi.service.environment.Constants.OS_HPUX
66             .equals(Platform.getOS())
67             || org.eclipse.osgi.service.environment.Constants.OS_AIX
68                     .equals(Platform.getOS())
69             || org.eclipse.osgi.service.environment.Constants.OS_LINUX
70                     .equals(Platform.getOS())
71             || org.eclipse.osgi.service.environment.Constants.OS_SOLARIS
72                     .equals(Platform.getOS());
73     private static FragmentEntry[] noFragments = new FragmentEntry[0];
74     private static Map JavaDoc table;
75
76     static {
77         table = new HashMap JavaDoc();
78         table.put("compatible", new Integer JavaDoc(IImport.RULE_COMPATIBLE)); //$NON-NLS-1$
79
table.put("perfect", new Integer JavaDoc(IImport.RULE_PERFECT)); //$NON-NLS-1$
80
table.put("equivalent", new Integer JavaDoc(IImport.RULE_EQUIVALENT)); //$NON-NLS-1$
81
table.put("greaterOrEqual", new Integer JavaDoc(IImport.RULE_GREATER_OR_EQUAL)); //$NON-NLS-1$
82
}
83
84     private static Writer JavaDoc writer;
85     // manage URL to File
86
private static Map JavaDoc urlFileMap;
87
88     private static Map JavaDoc localFileFragmentMap;
89     private static Stack JavaDoc bufferPool;
90     private static final int BUFFER_SIZE = 4096; // 4kbytes
91
private static final int INCREMENT_SIZE = 10240; // 10kbytes
92
/**
93      * return the urlString if it is a absolute URL
94      * otherwise, return the default URL if the urlString is null
95      * The defaultURL may point ot a file, create a file URL then
96      * if the urlString or the default URL are relatives, prepend the rootURL to it
97      */

98     public static URL JavaDoc getURL(URL JavaDoc rootURL, String JavaDoc urlString, String JavaDoc defaultURL) throws MalformedURLException JavaDoc {
99         URL JavaDoc url = null;
100
101         // if no URL , provide Default
102
if (urlString == null || urlString.trim().equals("")) { //$NON-NLS-1$
103

104             // no URL, no default, return right now...
105
if (defaultURL == null || defaultURL.trim().equals("")) //$NON-NLS-1$
106
return null;
107             else
108                 urlString = defaultURL;
109         }
110
111         // URL can be relative or absolute
112
if (urlString.startsWith("/") && urlString.length() > 1) //$NON-NLS-1$
113
urlString = urlString.substring(1);
114         try {
115             url = new URL JavaDoc(urlString);
116         } catch (MalformedURLException JavaDoc e) {
117             // the url is not an absolute URL
118
// try relative
119
url = new URL JavaDoc(rootURL, urlString);
120         }
121
122         return url;
123     }
124
125     /**
126      * return a relative String to rootURL
127      * if url contains rootURL so
128      * new URL(rootURL, resultString) == url
129      *
130      */

131     public static String JavaDoc getURLAsString(URL JavaDoc rootURL, URL JavaDoc url) {
132         String JavaDoc result = null;
133
134         if (rootURL == null) {
135             return (url == null) ? null : url.toString();
136         }
137
138         // if no URL , return null
139
if (url != null) {
140
141             result = url.toExternalForm();
142
143             if (rootURL.getHost() != null && !rootURL.getHost().equals(url.getHost()))
144                 return result;
145
146             if (rootURL.getProtocol() != null && !rootURL.getProtocol().equals(url.getProtocol()))
147                 return result;
148
149             if (rootURL.getPort() != url.getPort())
150                 return result;
151
152             String JavaDoc rootURLFileString = rootURL.getFile();
153             rootURLFileString = rootURLFileString.replace(File.separatorChar, '/');
154             if (!rootURLFileString.endsWith("/")) { //$NON-NLS-1$
155
int index = rootURLFileString.lastIndexOf('/');
156                 if (index != -1) {
157                     rootURLFileString = rootURLFileString.substring(0, index);
158                 }
159             }
160             String JavaDoc urlFileString = url.getFile();
161
162             if (urlFileString.startsWith(rootURLFileString)) {
163                 result = urlFileString.substring(rootURLFileString.length());
164                 result = result.replace(File.separatorChar, '/');
165             } else {
166                 // we need to check the following
167
// file:/C:/ and file:C:/
168
if ("file".equalsIgnoreCase(url.getProtocol())) { //$NON-NLS-1$
169
File JavaDoc rootFile = new File JavaDoc(rootURLFileString);
170                     File JavaDoc urlFile = new File JavaDoc(urlFileString);
171
172                     File JavaDoc relativePath = urlFile;
173                     while (relativePath != null && !rootFile.equals(relativePath.getParentFile())) {
174                         relativePath = relativePath.getParentFile();
175                     }
176
177                     if (relativePath == null) {
178                         UpdateCore.warn("Cannot calculate relative path"); //$NON-NLS-1$
179
return url.toString();
180                     } else {
181                         String JavaDoc relativeRootString = relativePath.getParentFile().getAbsolutePath();
182                         String JavaDoc fullString = urlFile.getAbsolutePath();
183                         if (!fullString.startsWith(relativeRootString)) {
184                             UpdateCore.warn("Full path:" + fullString + " does not start with " + relativeRootString); //$NON-NLS-1$ //$NON-NLS-2$
185
return url.toString();
186                         } else {
187                             String JavaDoc returnString = fullString.substring(relativeRootString.length() + 1);
188                             if (urlFile.isDirectory())
189                                 returnString += File.separator;
190                             // we lost the last slash when tranforming in File
191
returnString = returnString.replace(File.separatorChar, '/');
192                             return returnString;
193                         }
194
195                     }
196
197                 } else {
198                     result = url.toString();
199                 }
200             }
201         }
202
203         return result;
204     }
205
206     /**
207      * returns a translated String
208      */

209     public static String JavaDoc getResourceString(String JavaDoc infoURL, ResourceBundle JavaDoc bundle) {
210         String JavaDoc result = null;
211         if (infoURL != null) {
212             result = Platform.getResourceString(UpdateCore.getPlugin().getBundle(), infoURL, bundle);
213         }
214         return result;
215     }
216
217     /**
218      *
219      */

220     public static URL JavaDoc copyToLocal(InputStream JavaDoc sourceContentReferenceStream, String JavaDoc localName, InstallMonitor monitor) throws MalformedURLException JavaDoc, IOException JavaDoc, InstallAbortedException {
221         URL JavaDoc result = null;
222         // create the Dir if they do not exist
223
// get the path from the File to resolve File.separator..
224
// do not use the String as it may contain URL like separator
225
File JavaDoc localFile = new File JavaDoc(localName);
226         int index = localFile.getPath().lastIndexOf(File.separator);
227         if (index != -1) {
228             File JavaDoc dir = new File JavaDoc(localFile.getPath().substring(0, index));
229             if (!dir.exists())
230                 dir.mkdirs();
231         }
232
233         // transfer the content of the File
234
if (!localFile.isDirectory()) {
235             OutputStream JavaDoc localContentReferenceStream = new FileOutputStream JavaDoc(localFile);
236             try {
237                 Utilities.copy(sourceContentReferenceStream, localContentReferenceStream, monitor);
238             } finally {
239                 try {
240                     localContentReferenceStream.close();
241                 } catch (IOException JavaDoc e){}
242             }
243         }
244         result = localFile.toURL();
245         return result;
246     }
247
248     /*
249      * [20305] need to slam permissions for executable libs on some
250      * platforms. This is a temporary fix
251      */

252     public static void checkPermissions(ContentReference ref, String JavaDoc filePath) {
253
254         if (ref.getPermission() != 0) {
255             UpdateCore.warn("Change permission for " + filePath + " to " + ref.getPermission()); //$NON-NLS-1$ //$NON-NLS-2$
256
// FIXME: change the code to use JNI
257
}
258
259         if (filePath != null && OS_UNIX && ref.getPermission() != 0) {
260             // add execute permission on shared libraries 20305
261
// do not remove write permission 20896
262
// chmod a+x *.sl
263
try {
264                 Process JavaDoc pr = Runtime.getRuntime().exec(new String JavaDoc[] { "chmod", "a+x", filePath }); //$NON-NLS-1$ //$NON-NLS-2$
265
Thread JavaDoc chmodOutput = new StreamConsumer(pr.getInputStream());
266                 chmodOutput.setName("chmod output reader"); //$NON-NLS-1$
267
chmodOutput.start();
268                 Thread JavaDoc chmodError = new StreamConsumer(pr.getErrorStream());
269                 chmodError.setName("chmod error reader"); //$NON-NLS-1$
270
chmodError.start();
271             } catch (IOException JavaDoc ioe) {
272             }
273
274         }
275     }
276
277     /**
278      * Returns a random file name for the local system
279      * attempt to conserve the extension if there is a '.' in the path
280      * and no File.Seperator after the '.'
281      *
282      * \a\b\c.txt -> c987659385.txt
283      * c.txt -> c3854763.txt
284      * c -> c953867549
285      */

286     public static String JavaDoc getLocalRandomIdentifier(String JavaDoc remotePath, Date JavaDoc date) {
287         int dotIndex = remotePath.lastIndexOf("."); //$NON-NLS-1$
288
int fileIndex = remotePath.lastIndexOf(File.separator);
289         // if there is a separator after the dot
290
// do not consider it as an extension
291
String JavaDoc ext = (dotIndex != -1 && fileIndex < dotIndex) ? remotePath.substring(dotIndex) : ""; //$NON-NLS-1$
292
// the name is the string between the separator and the dot
293
// if there is no separator, it is the string up to the dot
294
// if there is no dot, go to the end of the string
295
if (fileIndex == -1)
296             fileIndex = 0;
297         if (dotIndex == -1)
298             dotIndex = remotePath.length();
299         // if I have a separator and no dot: /a/b/c -> c
300
// if my separator is the last /a/b/c/, fileIndex and dotIndex are the same, so it will return the default temp name
301
String JavaDoc name = (fileIndex < dotIndex) ? remotePath.substring(fileIndex, dotIndex) : "Eclipse_Update_TMP_"; //$NON-NLS-1$
302
String JavaDoc result = name + date.getTime() + ext;
303         return result;
304     }
305
306     /**
307      * remove a file or directory from the file system.
308      * used to clean up install
309      */

310     public static void removeFromFileSystem(File JavaDoc file) {
311         if (!file.exists() || !file.canWrite())
312             return;
313
314         if (file.isDirectory()) {
315             String JavaDoc[] files = file.list();
316             if (files != null) // be careful since file.list() can return null
317
for (int i = 0; i < files.length; ++i)
318                     removeFromFileSystem(new File JavaDoc(file, files[i]));
319         }
320
321         if (!file.delete()) {
322             String JavaDoc msg = NLS.bind(Messages.UpdateManagerUtils_UnableToRemoveFile, (new String JavaDoc[] { file.getAbsolutePath() }));
323             UpdateCore.log(msg, new Exception JavaDoc());
324         }
325     }
326
327     /**
328      * remove all the empty directories recursively
329      * used to clean up install
330      */

331     public static void removeEmptyDirectoriesFromFileSystem(File JavaDoc file) {
332         if (!file.isDirectory())
333             return;
334
335         String JavaDoc[] files = file.list();
336         if (files != null) { // be careful since file.list() can return null
337
for (int i = 0; i < files.length; ++i) {
338                 removeEmptyDirectoriesFromFileSystem(new File JavaDoc(file, files[i]));
339             }
340         }
341         if (!file.delete()) {
342             String JavaDoc msg = NLS.bind(Messages.UpdateManagerUtils_UnableToRemoveFile, (new String JavaDoc[] { file.getAbsolutePath() }));
343             UpdateCore.log(msg, new Exception JavaDoc());
344         }
345     }
346
347     /**
348      * Returns the plugin entries that are in source array and
349      * not in target array
350      */

351     public static IPluginEntry[] diff(IPluginEntry[] sourceArray, IPluginEntry[] targetArray) { // No pluginEntry to Install, return Nothing to instal
352
if (sourceArray == null || sourceArray.length == 0) {
353             return new IPluginEntry[0];
354         } // No pluginEntry installed, Install them all
355
if (targetArray == null || targetArray.length == 0) {
356             return sourceArray;
357         } // if a IPluginEntry from sourceArray is NOT in
358
// targetArray, add it to the list
359
List JavaDoc list1 = Arrays.asList(targetArray);
360         List JavaDoc result = new ArrayList JavaDoc(0);
361         for (int i = 0; i < sourceArray.length; i++) {
362             if (!list1.contains(sourceArray[i]))
363                 result.add(sourceArray[i]);
364         }
365
366         IPluginEntry[] resultEntry = new IPluginEntry[result.size()];
367         if (result.size() > 0)
368             result.toArray(resultEntry);
369         return resultEntry;
370     }
371
372     /**
373      * Returns the parent URL of the given URL, or <code>null</code> if the
374      * given URL is the root.
375      * <table>
376      * <caption>Example</caption>
377      * <tr>
378      * <th>Given URL</th>
379      * <th>Parent URL</th>
380      * <tr>
381      * <td>"http://hostname/"</td>
382      * <td>null</td>
383      * <tr>
384      * <td>"http://hostname/folder/file</td>
385      * <td>"http://hostname/folder/</td>
386      * </table>
387      *
388      * @param url a URL
389      * @return the parent of the given URL
390      */

391     public static URL JavaDoc getParent(URL JavaDoc url) {
392         String JavaDoc file = url.getFile();
393         int len = file.length();
394         if (len == 0 || len == 1 && file.charAt(0) == '/')
395             return null;
396         int lastSlashIndex = -1;
397         for (int i = len - 2; lastSlashIndex == -1 && i >= 0; --i) {
398             if (file.charAt(i) == '/')
399                 lastSlashIndex = i;
400         }
401         if (lastSlashIndex == -1)
402             file = ""; //$NON-NLS-1$
403
else
404             file = file.substring(0, lastSlashIndex + 1);
405         try {
406             url = new URL JavaDoc(url.getProtocol(), url.getHost(), url.getPort(), file);
407         } catch (MalformedURLException JavaDoc e) {
408             Assert.isTrue(false, e.getMessage());
409         }
410         return url;
411     }
412
413     /**
414      *
415      */

416     public static URL JavaDoc asDirectoryURL(URL JavaDoc url) throws MalformedURLException JavaDoc {
417         //url = URLEncoder.encode(url);
418
String JavaDoc path = url.getFile();
419         if (!path.endsWith("/")) { //$NON-NLS-1$
420
int index = path.lastIndexOf('/');
421             if (index != -1)
422                 path = path.substring(0, index + 1);
423             // ignore any ref in original URL
424
url = new URL JavaDoc(url.getProtocol(), url.getHost(), url.getPort(), path);
425         }
426         return url;
427     }
428
429     /*
430      * Compares two URL for equality
431      * Return false if one of them is null
432      */

433     public static boolean sameURL(URL JavaDoc url1, URL JavaDoc url2) {
434
435         if (url1 == null || url2 == null)
436             return false;
437         if (url1 == url2)
438             return true;
439         if (url1.equals(url2))
440             return true;
441
442         // check if URL are file: URL as we may
443
// have 2 URL pointing to the same featureReference
444
// but with different representation
445
// (i.e. file:/C;/ and file:C:/)
446
if (!"file".equalsIgnoreCase(url1.getProtocol())) //$NON-NLS-1$
447
return false;
448         if (!"file".equalsIgnoreCase(url2.getProtocol())) //$NON-NLS-1$
449
return false;
450
451         File JavaDoc file1 = getFileFor(url1);//new File(url1.getFile());
452
File JavaDoc file2 = getFileFor(url2);
453
454         if (file1 == null)
455             return false;
456
457         return (file1.equals(file2));
458     }
459     
460     /*
461      * Method getFileFor.
462      * @param url1
463      * @return File
464      */

465     private static File JavaDoc getFileFor(URL JavaDoc url1) {
466         if (urlFileMap == null) urlFileMap = new HashMap JavaDoc();
467         if (urlFileMap.get(url1)!=null) return (File JavaDoc)urlFileMap.get(url1);
468         File JavaDoc newFile = new File JavaDoc(url1.getFile());
469         urlFileMap.put(url1,newFile);
470         return newFile;
471     }
472
473     /*
474      * returns the list of FeatureReference that are parent of
475      * the Feature or an empty array if no parent found.
476      * @param onlyOptional if set to <code>true</code> only return parents that consider the feature optional
477      * @param child
478      * @param possiblesParent
479      */

480     public static IFeatureReference[] getParentFeatures(IFeature childFeature, IFeatureReference[] possiblesParent, boolean onlyOptional) throws CoreException {
481
482         if (childFeature == null)
483             return new IFeatureReference[0];
484
485         List JavaDoc parentList = new ArrayList JavaDoc();
486         IIncludedFeatureReference[] children = null;
487         IFeature compareFeature = null;
488         for (int i = 0; i < possiblesParent.length; i++) {
489             try {
490                 IFeature possibleParentFeature = possiblesParent[i].getFeature(null);
491                 if (possibleParentFeature != null) {
492                     children = possibleParentFeature.getIncludedFeatureReferences();
493                     for (int j = 0; j < children.length; j++) {
494                         try {
495                             compareFeature = children[j].getFeature(null);
496                         } catch (CoreException e) {
497                             UpdateCore.warn("", e); //$NON-NLS-1$
498
}
499                         if (childFeature.equals(compareFeature)) {
500                             if (onlyOptional) {
501                                 if (UpdateManagerUtils.isOptional(children[j])) {
502                                     parentList.add(possiblesParent[i]);
503                                 } else {
504                                     UpdateCore.warn("Feature :" + children[j] + " not optional. Not included in parents list."); //$NON-NLS-1$ //$NON-NLS-2$
505
}
506                             } else {
507                                 parentList.add(possiblesParent[i]);
508                             }
509                         }
510                     }
511                 }
512             } catch (CoreException e) {
513                 UpdateCore.warn("", e); //$NON-NLS-1$
514
}
515         }
516
517         IFeatureReference[] parents = new IFeatureReference[0];
518         if (parentList.size() > 0) {
519             parents = new IFeatureReference[parentList.size()];
520             parentList.toArray(parents);
521         }
522         return parents;
523     }
524
525     /*
526      * returns the list of Features that are parent of
527      * the Feature or an empty array if no parent found
528      * @param onlyOptional if set to <code>true</code> only return parents that consider the feature optional
529      * @param child
530      * @param possiblesParent
531      */

532     public static IFeatureReference[] getParentFeatures(IFeatureReference child, IFeatureReference[] possiblesParent, boolean onlyOptional) throws CoreException {
533
534         if (child == null)
535             return new IFeatureReference[0];
536
537         IFeature childFeature = null;
538         try {
539             childFeature = child.getFeature(null);
540         } catch (CoreException e) {
541             UpdateCore.warn(null, e);
542         }
543
544         if (childFeature == null)
545             return new IFeatureReference[0];
546
547         return getParentFeatures(childFeature, possiblesParent, onlyOptional);
548     }
549
550     /*
551      * If the return code of the HTTP connection is not 200 (OK)
552      * thow an IO exception
553      *
554      */

555     public static void checkConnectionResult(IResponse response,URL JavaDoc url) throws IOException JavaDoc {
556         // did the server return an error code ?
557
int result = response.getStatusCode();
558
559         if (result != IStatusCodes.HTTP_OK) {
560             String JavaDoc serverMsg = response.getStatusMessage();
561             response.close();
562             throw new FatalIOException(NLS.bind(Messages.ContentReference_HttpNok, (new Object JavaDoc[] { new Integer JavaDoc(result), serverMsg, url })));
563         }
564     }
565
566     public static class StreamConsumer extends Thread JavaDoc {
567         InputStream JavaDoc is;
568         byte[] buf;
569         public StreamConsumer(InputStream JavaDoc inputStream) {
570             super();
571             this.setDaemon(true);
572             this.is = inputStream;
573             buf = new byte[512];
574         }
575         public void run() {
576             try {
577                 int n = 0;
578                 while (n >= 0)
579                     n = is.read(buf);
580             } catch (IOException JavaDoc ioe) {
581             }
582         }
583     }
584
585     /**
586      * Return the optional children to install
587      * The optional features to install may not all be direct children
588      * of the feature.
589      * Also include non-optional features
590      *
591      * @param children all the nested features
592      * @param optionalfeatures optional features to install
593      * @return IFeatureReference[]
594      */

595     public static IFeatureReference[] optionalChildrenToInstall(IFeatureReference[] children, IFeatureReference[] optionalfeatures) {
596
597         List JavaDoc optionalChildrenToInstall = new ArrayList JavaDoc();
598         for (int i = 0; i < children.length; i++) {
599             IFeatureReference optionalFeature = children[i];
600             if (!UpdateManagerUtils.isOptional(optionalFeature)) {
601                 optionalChildrenToInstall.add(optionalFeature);
602             } else {
603                 for (int j = 0; j < optionalfeatures.length; j++) {
604                     if (optionalFeature.equals(optionalfeatures[j])) {
605                         optionalChildrenToInstall.add(optionalFeature);
606                         break;
607                     }
608                 }
609             }
610         }
611
612         IFeatureReference[] result = new IFeatureReference[optionalChildrenToInstall.size()];
613         if (optionalChildrenToInstall.size() > 0) {
614             optionalChildrenToInstall.toArray(result);
615         }
616
617         return result;
618     }
619
620     /**
621      * returns the mapping of matching rules
622      * the default returns perfect
623      *
624      * @since 2.0.2
625      */

626     public static int getMatchingRule(String JavaDoc rule) {
627         if (rule == null)
628             return IImport.RULE_COMPATIBLE;
629         int ruleInt = ((Integer JavaDoc) table.get(rule)).intValue();
630         if (ruleInt == IImport.RULE_NONE)
631             return IImport.RULE_PERFECT;
632         return ruleInt;
633     }
634     
635     /**
636      * returns the mapping of matching id rules
637      * the default returns perfect
638      *
639      * @since 2.0.2
640      */

641     public static int getMatchingIdRule(String JavaDoc rule) {
642         
643         if (rule == null)
644             return IImport.RULE_COMPATIBLE;
645         if (rule!=null && rule.equalsIgnoreCase("prefix")) //$NON-NLS-1$
646
return IImport.RULE_PREFIX;
647         return IImport.RULE_PERFECT;
648     }
649     
650     /**
651      * Method isOptional.
652      * @param featureReference
653      * @return boolean
654      */

655     public static boolean isOptional(IFeatureReference featureReference) {
656         if (featureReference==null) return false;
657         if (featureReference instanceof IIncludedFeatureReference){
658             return ((IIncludedFeatureReference)featureReference).isOptional();
659         }
660         return false;
661     }
662
663     /**
664      *
665      */

666     public static boolean isValidEnvironment(IPlatformEnvironment candidate) {
667         if (candidate==null) return false;
668         String JavaDoc os = candidate.getOS();
669         String JavaDoc ws = candidate.getWS();
670         String JavaDoc arch = candidate.getOSArch();
671         String JavaDoc nl = candidate.getNL();
672         if (os!=null && !isMatching(os, SiteManager.getOS())) return false;
673         if (ws!=null && !isMatching(ws, SiteManager.getWS())) return false;
674         if (arch!=null && !isMatching(arch, SiteManager.getOSArch())) return false;
675         if (nl!=null && !isMatchingLocale(nl, SiteManager.getNL())) return false;
676         return true;
677     }
678
679     /* Original code - commented out to provide a replacement as per bug 98387
680     
681     private static boolean isMatching(String candidateValues, String siteValues) {
682         if (siteValues==null) return false;
683         if ("*".equals(candidateValues)) return true; //$NON-NLS-1$
684         if ("".equals(candidateValues)) return true; //$NON-NLS-1$
685         siteValues = siteValues.toUpperCase();
686         StringTokenizer stok = new StringTokenizer(candidateValues, ","); //$NON-NLS-1$
687         while (stok.hasMoreTokens()) {
688             String token = stok.nextToken().toUpperCase();
689             if (siteValues.indexOf(token)!=-1) return true;
690         }
691         return false;
692     }
693     */

694     
695     /*
696      * Fixed bug 98387
697      */

698     
699     private static boolean isMatching(String JavaDoc candidateValues, String JavaDoc siteValues) {
700         if (siteValues==null) return false;
701         if ("*".equals(candidateValues)) return true; //$NON-NLS-1$
702
if ("".equals(candidateValues)) return true; //$NON-NLS-1$
703
StringTokenizer JavaDoc siteTokens = new StringTokenizer JavaDoc(siteValues, ","); //$NON-NLS-1$
704
//$NON-NLS-1$
705
while(siteTokens.hasMoreTokens()) {
706             StringTokenizer JavaDoc candidateTokens = new StringTokenizer JavaDoc
707                                            (candidateValues, ","); //$NON-NLS-1$
708
String JavaDoc siteValue = siteTokens.nextToken();
709             while (candidateTokens.hasMoreTokens()) {
710                 if (siteValue.equalsIgnoreCase
711                                  (candidateTokens.nextToken())) return true;
712             }
713         }
714         return false;
715     }
716
717     
718     /**
719      *
720      */

721     private static boolean isMatchingLocale(String JavaDoc candidateValues, String JavaDoc locale) {
722         if (locale==null) return false;
723         if ("*".equals(candidateValues)) return true; //$NON-NLS-1$
724
if ("".equals(candidateValues)) return true; //$NON-NLS-1$
725

726         locale = locale.toUpperCase();
727         candidateValues = candidateValues.toUpperCase();
728         StringTokenizer JavaDoc stok = new StringTokenizer JavaDoc(candidateValues, ","); //$NON-NLS-1$
729
while (stok.hasMoreTokens()) {
730             String JavaDoc candidate = stok.nextToken();
731             if (locale.indexOf(candidate) == 0)
732                 return true;
733             if (candidate.indexOf(locale) == 0)
734                 return true;
735         }
736         return false;
737     }
738
739     
740 /**
741  * write XML file
742  */

743 public static class Writer {
744
745     private PrintWriter JavaDoc w;
746     private OutputStream JavaDoc out;
747     private OutputStreamWriter JavaDoc outWriter;
748     private BufferedWriter JavaDoc buffWriter;
749     private String JavaDoc encoding;
750
751     /*
752      *
753      */

754     private Writer() {
755         super();
756     }
757     
758     public void init(File JavaDoc file, String JavaDoc encoding) throws FileNotFoundException JavaDoc, UnsupportedEncodingException JavaDoc{
759         this.encoding = encoding;
760         out = new FileOutputStream JavaDoc(file);
761         outWriter = new OutputStreamWriter JavaDoc(out, encoding);
762         buffWriter = new BufferedWriter JavaDoc(outWriter);
763         w = new PrintWriter JavaDoc(buffWriter);
764     }
765
766     
767     /*
768      *
769      */

770     public void write(IWritable element) {
771         w.println("<?xml version=\"1.0\" encoding=\""+encoding+"\"?>"); //$NON-NLS-1$ //$NON-NLS-2$
772
w.println(""); //$NON-NLS-1$
773
w.println("<!-- File written by Update manager 2.0 -->"); //$NON-NLS-1$
774
w.println("<!-- comments in this file are not preserved -->"); //$NON-NLS-1$
775
w.println(""); //$NON-NLS-1$
776
element.write(0, w);
777         close();
778     }
779     
780     /*
781      *
782      */

783      public void close(){
784             w.close();
785      }
786
787     /*
788      *
789      */

790     private static void appendEscapedChar(StringBuffer JavaDoc buffer, char c) {
791         String JavaDoc replacement = getReplacement(c);
792         if (replacement != null) {
793             buffer.append('&');
794             buffer.append(replacement);
795             buffer.append(';');
796         } else {
797             if ((c >= ' ' && c <= 0x7E) || c == '\n' || c == '\r' || c == '\t') {
798                 buffer.append(c);
799             } else {
800                 buffer.append("&#"); //$NON-NLS-1$
801
buffer.append(Integer.toString(c));
802                 buffer.append(';');
803             }
804         }
805     }
806
807     /*
808      *
809      */

810     public static String JavaDoc xmlSafe(String JavaDoc s) {
811         StringBuffer JavaDoc result = new StringBuffer JavaDoc(s.length() + 10);
812         for (int i = 0; i < s.length(); ++i)
813             appendEscapedChar(result, s.charAt(i));
814         return result.toString();
815     }
816     
817     /*
818      *
819      */

820     private static String JavaDoc getReplacement(char c) {
821         // Encode special XML characters into the equivalent character references.
822
// These five are defined by default for all XML documents.
823
switch (c) {
824             case '<' :
825                 return "lt"; //$NON-NLS-1$
826
case '>' :
827                 return "gt"; //$NON-NLS-1$
828
case '"' :
829                 return "quot"; //$NON-NLS-1$
830
case '\'' :
831                 return "apos"; //$NON-NLS-1$
832
case '&' :
833                 return "amp"; //$NON-NLS-1$
834
}
835         return null;
836     }
837 }
838     public static Writer JavaDoc getWriter(File JavaDoc file,String JavaDoc encoding) throws FileNotFoundException JavaDoc, UnsupportedEncodingException JavaDoc {
839         if (writer==null) writer = new Writer JavaDoc();
840         writer.init(file,encoding);
841         return writer;
842     }
843     
844     public static boolean isSameTimestamp(URL JavaDoc url, long timestamp) {
845         try {
846             if (UpdateCore.getPlugin().getUpdateSession().isVisited(url)) {
847                 return true;
848             }
849             URL JavaDoc resolvedURL = URLEncoder.encode(url);
850             IResponse response = ConnectionFactory.get(resolvedURL);
851             long remoteLastModified = response.getLastModified();
852             // 2 seconds tolerance, as some OS's may round up the time stamp
853
// to the closest second. For safety, we make it 2 seconds.
854
return Math.abs(remoteLastModified - timestamp)/1000 <= 2;
855         } catch (MalformedURLException JavaDoc e) {
856             return false;
857         } catch (IOException JavaDoc e) {
858             return false;
859         }
860     }
861     /**
862      * The file is associated with a lookup key.
863      * @param key optional lookup key, or <code>null</code>.
864      * @param temp the local working file
865      */

866     public synchronized static void mapLocalFileFragment(String JavaDoc key, FileFragment temp) {
867         // create file association
868
if (key != null) {
869             if (localFileFragmentMap == null)
870                 localFileFragmentMap = new HashMap JavaDoc();
871             localFileFragmentMap.put(key, temp);
872         }
873     }
874
875     /**
876      * The file is associated with a lookup key.
877      * @param key optional lookup key, or <code>null</code>.
878      */

879     public synchronized static void unMapLocalFileFragment(String JavaDoc key) {
880         // remove file association
881
if (key != null && localFileFragmentMap !=null) {
882             localFileFragmentMap.remove(key);
883         }
884     }
885     
886     /**
887      * Returns a previously cached local file (in temporary area) matching the
888      * specified key.
889      *
890      * @param key lookup key
891      * @return cached file, or <code>null</code>.
892      */

893     public static synchronized FileFragment lookupLocalFileFragment(String JavaDoc key) {
894         if (localFileFragmentMap == null)
895             return null;
896         return (FileFragment) localFileFragmentMap.get(key);
897     }
898     
899     /**
900      * Copies specified input stream to the output stream. Neither stream
901      * is closed as part of this operation.
902      *
903      * @param is input stream
904      * @param os output stream
905      * @param monitor progress monitor
906      * @param expectedLength - if > 0, the number of bytes from InputStream will be verified
907      * @@return the offset in the input stream where copying stopped. Returns -1 if end of input stream is reached.
908      * @since 2.0
909      */

910     public static long copy(InputStream JavaDoc is, OutputStream JavaDoc os, InstallMonitor monitor, long expectedLength) {
911         byte[] buf = getBuffer();
912         long offset=0;
913         try {
914             int len = is.read(buf);
915             int nextIncrement = 0;
916             while (len != -1) {
917                 os.write(buf, 0, len);
918                     offset += len;
919                 if (monitor != null) {
920                     nextIncrement += len;
921                     // update monitor periodically
922
if (nextIncrement >= INCREMENT_SIZE){
923                         monitor.incrementCount(nextIncrement);
924                         nextIncrement = 0;
925                     }
926                     if (monitor.isCanceled()) {
927                         return offset;
928                     }
929                 }
930                 if (expectedLength > 0 && offset == expectedLength) {
931                     // everything read do not return offset, otherwise trying
932
// to read again from this offset will result in HTTP 416
933
break;
934                 }
935                 
936                 len = is.read(buf);
937             }
938             if (nextIncrement > 0 && monitor != null)
939                 monitor.incrementCount(nextIncrement);
940             if(expectedLength>0 && offset!=expectedLength)
941                 throw new IOException JavaDoc(NLS.bind(Messages.UpdateManagerUtils_inputStreamEnded, (new String JavaDoc[] { String.valueOf(offset), String.valueOf(expectedLength) })));
942             return -1;
943         } catch(IOException JavaDoc e){
944             // Log the actual error, as this is no longer
945
// passed up the calling stack
946
UpdateCore.log(Messages.UpdateManagerUtils_copy + offset, e);
947             return offset;
948         } finally {
949             freeBuffer(buf);
950         }
951     }
952
953     public static class CopyException extends Exception JavaDoc {
954         
955         private static final long serialVersionUID = 1L;
956         Exception JavaDoc rootException;
957         int bytesCopied;
958
959         /**
960          *
961          */

962         public CopyException(Exception JavaDoc rootException, int bytesCopied) {
963             super();
964             this.rootException= rootException;
965             this.bytesCopied=bytesCopied;
966         }
967         /**
968          * Instance of IOException or InstallAbortedException
969          * @return
970          */

971         public Exception JavaDoc getRootException(){
972             return rootException;
973         }
974         public int getBytesCopied(){
975             return bytesCopied;
976         }
977
978     }
979     
980     private static synchronized byte[] getBuffer() {
981         if (bufferPool == null) {
982             return new byte[BUFFER_SIZE];
983         }
984
985         try {
986             return (byte[]) bufferPool.pop();
987         } catch (EmptyStackException JavaDoc e) {
988             return new byte[BUFFER_SIZE];
989         }
990     }
991
992     private static synchronized void freeBuffer(byte[] buf) {
993         if (bufferPool == null)
994             bufferPool = new Stack JavaDoc();
995         bufferPool.push(buf);
996     }
997     
998     
999     /**
1000     * Returns a list of fragments. Zero length if no fragments.
1001     * @param bundle the bundle to get fragments for
1002     */

1003    public static FragmentEntry[] getFragments(Bundle JavaDoc bundle) {
1004        PackageAdmin pkgAdmin = UpdateCore.getPlugin().getPackageAdmin();
1005        Bundle JavaDoc[] fragmentBundles = pkgAdmin.getFragments(bundle);
1006        if (fragmentBundles == null)
1007            return noFragments;
1008        
1009        FragmentEntry[] fragments = new FragmentEntry[fragmentBundles.length];
1010        for (int i = 0; i < fragments.length; i++) {
1011            fragments[i] = new FragmentEntry((String JavaDoc) fragmentBundles[i]
1012                    .getHeaders().get(Constants.BUNDLE_SYMBOLICNAME),
1013                    (String JavaDoc) fragmentBundles[i].getHeaders().get(
1014                            Constants.BUNDLE_VERSION), Platform
1015                            .getResourceString(fragmentBundles[i],
1016                                    (String JavaDoc) fragmentBundles[i].getHeaders()
1017                                            .get(Constants.BUNDLE_VERSION)),
1018                    fragmentBundles[i].getLocation());
1019        }
1020        return fragments;
1021    }
1022    
1023    public static String JavaDoc getWritableXMLString(String JavaDoc value) {
1024        StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
1025        if(value == null)
1026            return buf.toString();
1027        for (int i = 0; i < value.length(); i++) {
1028            char c = value.charAt(i);
1029            switch (c) {
1030                case '&' :
1031                    buf.append("&amp;"); //$NON-NLS-1$
1032
break;
1033                case '<' :
1034                    buf.append("&lt;"); //$NON-NLS-1$
1035
break;
1036                case '>' :
1037                    buf.append("&gt;"); //$NON-NLS-1$
1038
break;
1039                case '\'' :
1040                    buf.append("&apos;"); //$NON-NLS-1$
1041
break;
1042                case '\"' :
1043                    buf.append("&quot;"); //$NON-NLS-1$
1044
break;
1045                default :
1046                    buf.append(c);
1047                    break;
1048            }
1049        }
1050        return buf.toString();
1051    }
1052    
1053    public static LiteFeature[] getLightFeatures(ExtendedSite site) {
1054        
1055        URL JavaDoc fullDigestURL;
1056        try {
1057            fullDigestURL = getFullDigestURL( site, Locale.getDefault().getCountry(), Locale.getDefault().getLanguage());
1058        } catch (MalformedURLException JavaDoc e) {
1059            UpdateCore.log("Could not access digest on the site: " + e.getMessage(), null); //$NON-NLS-1$
1060
return null;
1061        }
1062        
1063        Digest digest = new Digest( fullDigestURL);
1064        try {
1065            LiteFeature[] features = (LiteFeature[])digest.parseDigest();
1066            for(int i = 0; i < features.length; i++) {
1067                features[i].setSite(site);
1068            }
1069            return features;
1070        } catch(Exception JavaDoc e){
1071            UpdateCore.log("Digest could not be parsed:" + e.getMessage(), null); //$NON-NLS-1$
1072
return null;
1073        }
1074    }
1075    
1076    private static URL JavaDoc getFullDigestURL(ExtendedSite site, String JavaDoc country, String JavaDoc language) throws MalformedURLException JavaDoc {
1077        
1078        String JavaDoc digestURL = (site.getDigestURL().endsWith("/")? site.getDigestURL(): site.getDigestURL() + "/"); //$NON-NLS-1$ //$NON-NLS-2$
1079

1080        if (digestURL.indexOf("://") == -1) { //$NON-NLS-1$
1081
String JavaDoc siteURL = site.getLocationURL().toExternalForm();
1082            if (siteURL.endsWith(Site.SITE_XML)) {
1083                siteURL = siteURL.substring(0, siteURL.length() - Site.SITE_XML.length());
1084            }
1085            if (digestURL.equals("/")) { //$NON-NLS-1$
1086
digestURL = siteURL;
1087            } else {
1088                if (digestURL.startsWith("/")) { //$NON-NLS-1$
1089
digestURL = digestURL.substring(1, digestURL.length());
1090                }
1091                digestURL = siteURL + digestURL;
1092            }
1093        }
1094        
1095        digestURL += "digest"; //$NON-NLS-1$
1096

1097        if ( isLocalSupported(site, country, language)) {
1098            return new URL JavaDoc(digestURL + "_" + language + "_" + country + ".zip"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
1099
}
1100        if ( isLangaugeSupported(site, language)) {
1101            return new URL JavaDoc(digestURL + "_" + language + ".zip"); //$NON-NLS-1$ //$NON-NLS-2$
1102
}
1103        return new URL JavaDoc(digestURL + ".zip"); //$NON-NLS-1$
1104
}
1105
1106    private static boolean isLangaugeSupported(ExtendedSite site, String JavaDoc language) {
1107        String JavaDoc[] availableLanguages = site.getAvailableLocals();
1108        if ((availableLanguages == null) || (availableLanguages.length == 0)) {
1109            return false;
1110        }
1111        for(int i = 0; i < availableLanguages.length; i++) {
1112            if (availableLanguages[i].equals(language)) {
1113                return true;
1114            }
1115        }
1116        return false;
1117    }
1118
1119    private static boolean isLocalSupported(ExtendedSite site, String JavaDoc country, String JavaDoc language) {
1120        String JavaDoc localeCode = language + "_" + country; //$NON-NLS-1$
1121
String JavaDoc[] availableLocals = site.getAvailableLocals();
1122        if ((availableLocals == null) || (availableLocals.length == 0)) {
1123            return false;
1124        }
1125        for(int i = 0; i < availableLocals.length; i++) {
1126            if (availableLocals[i].equals(localeCode)) {
1127                return true;
1128            }
1129        }
1130        return false;
1131    }
1132}
1133
Popular Tags