KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > update > internal > search > UpdatePolicy


1 /*******************************************************************************
2  * Copyright (c) 2000, 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  * James D Miles (IBM Corp.) - bug 191368, Policy URL doesn't support UTF-8 characters
11  *******************************************************************************/

12 package org.eclipse.update.internal.search;
13
14 import java.io.IOException JavaDoc;
15 import java.io.InputStream JavaDoc;
16 import java.net.MalformedURLException JavaDoc;
17 import java.net.URL JavaDoc;
18 import java.util.ArrayList JavaDoc;
19
20 import javax.xml.parsers.DocumentBuilder JavaDoc;
21 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
22 import javax.xml.parsers.ParserConfigurationException JavaDoc;
23
24 import org.eclipse.core.runtime.CoreException;
25 import org.eclipse.core.runtime.IProgressMonitor;
26 import org.eclipse.osgi.util.NLS;
27 import org.eclipse.update.core.ISite;
28 import org.eclipse.update.core.Utilities;
29 import org.eclipse.update.internal.core.Messages;
30 import org.eclipse.update.internal.core.URLEncoder;
31 import org.eclipse.update.internal.core.UpdateManagerUtils;
32 import org.eclipse.update.internal.core.connection.ConnectionFactory;
33 import org.eclipse.update.internal.core.connection.IResponse;
34 import org.eclipse.update.search.IUpdateSiteAdapter;
35 import org.w3c.dom.Document JavaDoc;
36 import org.w3c.dom.NamedNodeMap JavaDoc;
37 import org.w3c.dom.Node JavaDoc;
38 import org.w3c.dom.NodeList JavaDoc;
39 import org.xml.sax.InputSource JavaDoc;
40 import org.xml.sax.SAXException JavaDoc;
41
42 /**
43  *
44  * This class opens connection to the update map resource
45  * and parses the file to load update URL mappings.
46  * These mappings are used to redirect new updates search
47  * when the redirection pattern matches.
48  */

49
50 public class UpdatePolicy {
51     private static final String JavaDoc TAG_POLICY = "update-policy"; //$NON-NLS-1$
52
private static final String JavaDoc TAG_URL_MAP = "url-map"; //$NON-NLS-1$
53
private static final String JavaDoc ATT_URL = "url"; //$NON-NLS-1$
54
private static final String JavaDoc ATT_PATTERN = "pattern"; //$NON-NLS-1$
55
private static final String JavaDoc ATT_TYPE = "url-type"; //$NON-NLS-1$
56
private static final String JavaDoc ATT_TYPE_VALUE_UPDATE = "update"; //$NON-NLS-1$
57
//private static final String ATT_TYPE_VALUE_BOTH = "both"; //$NON-NLS-1$
58
private static final String JavaDoc ATT_TYPE_VALUE_DISCOVERY = "discovery"; //$NON-NLS-1$
59

60     private static final DocumentBuilderFactory JavaDoc documentBuilderFactory = DocumentBuilderFactory.newInstance();
61
62     private static class MapSite implements IUpdateSiteAdapter {
63         private URL JavaDoc url;
64         public MapSite(URL JavaDoc url) {
65             this.url = url;
66         }
67         public String JavaDoc getLabel() {
68             if (url == null) {
69                 return ""; //$NON-NLS-1$
70
}
71             return url.toString();
72         }
73         public URL JavaDoc getURL() {
74             return url;
75         }
76     }
77
78     private static class UpdateMapEntry {
79         private IUpdateSiteAdapter site;
80         private String JavaDoc pattern;
81
82         public UpdateMapEntry(String JavaDoc pattern, URL JavaDoc url) {
83             this.pattern = pattern;
84             this.site = new MapSite(url);
85         }
86         public IUpdateSiteAdapter getSite() {
87             return site;
88         }
89         public boolean matches(String JavaDoc id) {
90             return id.startsWith(pattern);
91         }
92         public String JavaDoc getPattern() {
93             return pattern;
94         }
95     }
96
97     private ArrayList JavaDoc entries;
98     private ArrayList JavaDoc discoveryEntries;
99     private IUpdateSiteAdapter defaultSite;
100     private IUpdateSiteAdapter defaultDiscoverySite;
101     private boolean loaded = false;
102     private boolean fallbackAllowed = true;
103
104     public UpdatePolicy() {
105         entries = new ArrayList JavaDoc();
106         discoveryEntries = new ArrayList JavaDoc();
107     }
108
109     public void load(URL JavaDoc mapFile, IProgressMonitor monitor)
110         throws CoreException {
111         InputStream JavaDoc policyStream = null;
112         try {
113             IResponse response = ConnectionFactory.get(mapFile);
114             UpdateManagerUtils.checkConnectionResult(response, mapFile);
115             policyStream = response.getInputStream(monitor);
116             // the stream can be null if the user cancels the connection
117
if (policyStream == null)
118                 return;
119             
120             documentBuilderFactory.setNamespaceAware(true);
121             DocumentBuilder JavaDoc parser = documentBuilderFactory.newDocumentBuilder();
122             Document JavaDoc doc = parser.parse(new InputSource JavaDoc(policyStream));
123
124             processUpdatePolicy(doc);
125             loaded = true;
126         } catch (IOException JavaDoc e) {
127             throw Utilities.newCoreException(
128                 NLS.bind(Messages.SiteURLFactory_UnableToAccessSiteStream, (new String JavaDoc[] { mapFile == null ? "" : mapFile.toExternalForm() })), //$NON-NLS-1$
129
ISite.SITE_ACCESS_EXCEPTION,
130                 e);
131         } catch (SAXException JavaDoc e) {
132             throw Utilities.newCoreException(
133                 Messages.UpdatePolicy_parsePolicy,
134                 0,
135                 e);
136
137         } catch(ParserConfigurationException JavaDoc e) {
138             throw Utilities.newCoreException(
139                 Messages.UpdatePolicy_parsePolicy,
140                 0,
141                 e);
142         } finally {
143             if (policyStream != null) {
144                 try {
145                     policyStream.close();
146                 } catch (IOException JavaDoc e) {
147                 }
148             }
149         }
150     }
151
152     public boolean isLoaded() {
153         return loaded;
154     }
155     
156     /*
157      * Given the feature ID, returns the mapped update URL if
158      * found in the mappings. This URL will be used INSTEAD of
159      * the update URL encoded in the feature itself during the
160      * new update search.
161      * <p>In case of multiple matches (e.g. org.eclipse and org.eclipse.platform)
162      * the URL for the longer pattern will be picked (i.e. org.eclipse.platform).
163      */

164     public IUpdateSiteAdapter getMappedSite(String JavaDoc id) {
165         UpdateMapEntry lastEntry = null;
166         for (int i = 0; i < entries.size(); i++) {
167             UpdateMapEntry entry = (UpdateMapEntry) entries.get(i);
168             if (entry.matches(id)) {
169                 if (lastEntry == null)
170                     lastEntry = entry;
171                 else {
172                     // Choose the match with longer pattern.
173
// For example, if two matches are found:
174
// 'org.eclipse' and 'org.eclipse.platform',
175
// pick 'org.eclipse.platform'.
176
String JavaDoc pattern = entry.getPattern();
177                     String JavaDoc lastPattern = lastEntry.getPattern();
178                     if (pattern.length() > lastPattern.length())
179                         lastEntry = entry;
180                 }
181             }
182         }
183         if (lastEntry != null)
184             return lastEntry.getSite();
185         else
186             return defaultSite;
187     }
188     
189     /*
190      * Given the feature ID, returns the mapped discovery URL if
191      * found in the mappings. This URL will be used INSTEAD of
192      * the discovery URL encoded in the feature itself during the
193      * new search.
194      * <p>In case of multiple matches (e.g. org.eclipse and org.eclipse.platform)
195      * the URL for the longer pattern will be picked (i.e. org.eclipse.platform).
196      */

197     public IUpdateSiteAdapter getMappedDiscoverySite(String JavaDoc id) {
198         UpdateMapEntry lastEntry = null;
199         for (int i = 0; i < discoveryEntries.size(); i++) {
200             UpdateMapEntry entry = (UpdateMapEntry) discoveryEntries.get(i);
201             if (entry.matches(id)) {
202                 if (lastEntry == null)
203                     lastEntry = entry;
204                 else {
205                     // Choose the match with longer pattern.
206
// For example, if two matches are found:
207
// 'org.eclipse' and 'org.eclipse.platform',
208
// pick 'org.eclipse.platform'.
209
String JavaDoc pattern = entry.getPattern();
210                     String JavaDoc lastPattern = lastEntry.getPattern();
211                     if (pattern.length() > lastPattern.length())
212                         lastEntry = entry;
213                 }
214             }
215         }
216         if (lastEntry != null)
217             return lastEntry.getSite();
218         else
219             return defaultDiscoverySite;
220     }
221
222     public boolean isFallbackAllowed() {
223         return fallbackAllowed;
224     }
225     
226     private void reset() {
227         if (!entries.isEmpty())
228             entries.clear();
229         if (!discoveryEntries.isEmpty())
230             discoveryEntries.clear();
231     }
232
233     private void processUpdatePolicy(Document JavaDoc document) throws CoreException {
234         Node JavaDoc root = document.getDocumentElement();
235         reset();
236         
237         if (root.getNodeName().equals(TAG_POLICY)==false)
238             throwCoreException("'"+TAG_POLICY+Messages.UpdatePolicy_policyExpected, null); //$NON-NLS-1$
239

240         NodeList JavaDoc nodes = root.getChildNodes();
241         
242         for (int i=0; i<nodes.getLength(); i++) {
243             Node JavaDoc child = nodes.item(i);
244             if (child.getNodeType() != Node.ELEMENT_NODE)
245                 continue;
246             String JavaDoc tag = child.getNodeName();
247             if (tag.equals(TAG_URL_MAP))
248                 processMapNode(child);
249         }
250     }
251     private void processMapNode(Node JavaDoc node) throws CoreException {
252         String JavaDoc pattern = getAttribute(node, ATT_PATTERN);
253         String JavaDoc urlName = getAttribute(node, ATT_URL);
254         String JavaDoc type = getAttribute(node, ATT_TYPE);
255         
256         assertNotNull(ATT_PATTERN, pattern);
257         assertNotNull(ATT_URL, urlName);
258         
259         // empty url means feature is not updateable
260
if (urlName.trim().length() == 0) {
261             addUpdateEntry(pattern, null, type);
262             return;
263         }
264
265         try {
266             URL JavaDoc url = new URL JavaDoc(urlName);
267             URL JavaDoc resolvedURL = URLEncoder.encode(url);
268             addUpdateEntry(pattern, resolvedURL, type);
269         } catch (MalformedURLException JavaDoc e) {
270             throwCoreException(Messages.UpdatePolicy_invalidURL+urlName, null);
271         }
272     }
273     
274     private void assertNotNull(String JavaDoc name, String JavaDoc value) throws CoreException {
275         if (value==null)
276             throwCoreException(name+Messages.UpdatePolicy_nameNoNull, null);
277     }
278     
279     private String JavaDoc getAttribute(Node JavaDoc node, String JavaDoc name) {
280         NamedNodeMap JavaDoc attMap = node.getAttributes();
281         Node JavaDoc att = attMap.getNamedItem(name);
282         if (att==null) return null;
283         return att.getNodeValue();
284     }
285
286     private void addUpdateEntry(String JavaDoc pattern, URL JavaDoc url, String JavaDoc type) {
287         if (pattern.equalsIgnoreCase("*")) {//$NON-NLS-1$
288
if (type == null)
289                 defaultSite = new MapSite(url);
290             else if (type.equals(ATT_TYPE_VALUE_UPDATE))
291                 defaultSite = new MapSite(url);
292             else if (type.equals(ATT_TYPE_VALUE_DISCOVERY))
293                 defaultDiscoverySite = new MapSite(url);
294             else {
295                 defaultSite = new MapSite(url);
296                 defaultDiscoverySite = new MapSite(url);
297             }
298         } else {
299             if (type == null )
300                 entries.add(new UpdateMapEntry(pattern, url));
301             else if (type.equals(ATT_TYPE_VALUE_UPDATE))
302                 entries.add(new UpdateMapEntry(pattern, url));
303             else if (type.equals(ATT_TYPE_VALUE_DISCOVERY))
304                 discoveryEntries.add(new UpdateMapEntry(pattern, url));
305             else {
306                 entries.add(new UpdateMapEntry(pattern, url));
307                 discoveryEntries.add(new UpdateMapEntry(pattern, url));
308             }
309         }
310     }
311     
312     private void throwCoreException(String JavaDoc message, Throwable JavaDoc e) throws CoreException {
313         String JavaDoc fullMessage = Messages.UpdatePolicy_UpdatePolicy+message;
314         throw Utilities.newCoreException(fullMessage, 0, e);
315     }
316 }
317
Popular Tags