KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > jetspeed > services > urlmanager > JetspeedURLManagerService


1 /*
2  * Copyright 2000-2001,2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.jetspeed.services.urlmanager;
18
19 // Java classes
20
import java.util.HashMap JavaDoc;
21 import java.util.Hashtable JavaDoc;
22 import java.util.Iterator JavaDoc;
23 import java.util.List JavaDoc;
24 import java.util.Map JavaDoc;
25 import java.util.Vector JavaDoc;
26 import java.io.BufferedWriter JavaDoc;
27 import java.io.File JavaDoc;
28 import java.io.FileWriter JavaDoc;
29 import java.io.PrintWriter JavaDoc;
30
31 import javax.servlet.ServletConfig JavaDoc;
32 import javax.servlet.ServletContext JavaDoc;
33
34 // Turbine classes
35
import org.apache.turbine.services.TurbineBaseService;
36
37 // Velocity classes
38
import org.apache.velocity.runtime.configuration.Configuration;
39
40 // Jetspeed classes
41
import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
42 import org.apache.jetspeed.services.logging.JetspeedLogger;
43 import org.apache.jetspeed.services.resources.JetspeedResources;
44
45 /**
46  * <p>This implementation of the URLManagerService is backed by a simple
47  * map persisted on disk in a properties file</p>
48  * Added: Support for proxies. <br>
49  * Example: (Set in <code>JetspeedResources.properties</code>)<br>
50  * <code>services.URLManager.proxy.http.host=myproxy.mydomain</code><br>
51  * <code>services.URLManager.proxy.http.port=81</code><br>
52  *
53  * @see URLManagerService
54  * @author <a HREF="mailto:raphael@apache.org">Raphaël Luta</a>
55  * @author <a HREF="mailto:sgala@hisitech.com">Santiago Gala</a>
56  * @version $Id: JetspeedURLManagerService.java,v 1.16 2004/02/23 03:30:47 jford Exp $
57  */

58 public class JetspeedURLManagerService extends TurbineBaseService implements URLManagerService
59 {
60     /**
61      * Static initialization of the logger for this class
62      */

63     private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(JetspeedURLManagerService.class.getName());
64     
65     /**
66     Map used to store all URL Information.
67     */

68     private Map JavaDoc urls = new HashMap JavaDoc();
69
70     /**
71     Path to the properties file used for persisting the data
72     */

73     private String JavaDoc path = null;
74
75     /**
76     Hashtable to store proxy configuration in
77     */

78     private Hashtable JavaDoc proxies = new Hashtable JavaDoc();
79
80     /**
81      * Late init. Don't return control until early init says we're done.
82      */

83     public void init( )
84     {
85         while( !getInit() ) {
86             try {
87                 Thread.sleep(500);
88             } catch (InterruptedException JavaDoc ie ) {
89                 logger.info("URLManager service: Waiting for init()..." );
90             }
91         }
92
93     }
94
95
96
97     /**
98      * Called during Turbine.init()
99      *
100      * @param config A ServletConfig.
101      */

102     public synchronized void init( ServletConfig JavaDoc config )
103     {
104         //We have already been initialized...
105
if( getInit() ) return;
106
107         try
108         {
109             logger.info ( "JetspeedURLManagerService early init()....starting!");
110
111         // Proxy Settings are stored as 'services.URLManager.proxy.<protocol>.port' and as
112
// 'services.URLManager.proxy.<protocol>.port' in JetspeedResource.properties.
113
// Get a list of settings and store them in the hashtable
114
String JavaDoc prefix = "services." + URLManagerService.SERVICE_NAME + ".proxy.";
115             Iterator JavaDoc resourceKeys = JetspeedResources.getKeys( prefix );
116
117             String JavaDoc key, hashKey;
118             Object JavaDoc hashValue = null;
119             while( resourceKeys.hasNext() )
120             {
121                 key = (String JavaDoc)resourceKeys.next();
122                 hashKey = key.substring(prefix.length()).toLowerCase();
123                 if ( hashKey.endsWith(".host") )
124                 {
125                     hashValue = JetspeedResources.getString(key);
126                     proxies.put( hashKey, hashValue );
127                 }
128                 else if ( hashKey.endsWith(".port") )
129                 {
130                     hashValue = new Integer JavaDoc(JetspeedResources.getInt(key));
131                     proxies.put( hashKey, hashValue );
132                 }
133             }
134
135             path = JetspeedResources.getString( "services."+URLManagerService.SERVICE_NAME+".url" );
136
137             if ( path == null)
138             {
139                 String JavaDoc tempdir = new String JavaDoc("WEB-INF/conf/datasources.properties");
140                 String JavaDoc ps = System.getProperty("file.separator");
141
142                 try
143                 {
144                     ServletContext JavaDoc sc = config.getServletContext();
145                     tempdir = sc.getAttribute("javax.servlet.context.tempdir").toString()
146                                            + ps + "jetspeed"
147                                            + ps + "conf"
148                                            + ps + "datasources.properties";
149                     logger.debug("URLMangler: will create file in servlet temp directory " + tempdir);
150                 }
151                 catch (Exception JavaDoc e)
152                 {
153                     logger.debug("URLMangler: problems creating file in servlet temp directory "
154                            + " falling back to WEB-INF/conf : " + e);
155                 }
156                 path = tempdir;
157             }
158             else
159             {
160                 logger.debug("URLMangler: will create file in user configured " + path);
161                 path = config.getServletContext().getRealPath(path);
162                 // should test for writability here and fallback to servlet tmp directory on failure
163
}
164
165             load();
166             logger.info ( "JetspeedURLManagerService early init()....finished!");
167         }
168         catch (Throwable JavaDoc t)
169         {
170             logger.error ( "Cannot initialize JetspeedURLManagerService!", t );
171         }
172         setInit(true);
173
174     }
175
176     /**
177      * Called during Turbine destroy(). Persist the Manager state
178      * to disk
179      */

180     public void shutdown() {
181         save();
182     }
183
184     /**
185      * Registers a new URL record. If the url is already registered in
186      * the system, doesn't modify the current record.
187      *
188      * @param url the url to register
189      */

190     public void register( String JavaDoc url ) {
191         if ( url != null ) {
192             URLInfo info = getInfo( url );
193             if ( info == null ) {
194                 register( new URLInfo( url, URLManagerService.STATUS_OK ) );
195             }
196         }
197     }
198
199     /**
200      * Registers a new URL record. If the url is already registered in
201      * the system, updates the status of this URL info record
202      *
203      * @param url the url to register
204      * @param status the status of this url
205      */

206     public void register( String JavaDoc url, int status ) {
207         if ( url != null ) {
208             URLInfo info = getInfo( url );
209             if ( info == null ) {
210                 register( new URLInfo( url, status ) );
211             } else {
212                 info.setStatus( status );
213             }
214         }
215     }
216
217     /**
218      * Registers a new URL record. If the url is already registered in
219      * the system, updates both the status and the message of this URL
220      * info record
221      *
222      * @param url the url to register
223      * @param status the status of this url
224      * @param message a descriptive message of the status
225      */

226     public void register( String JavaDoc url, int status, String JavaDoc message ) {
227         if ( url != null ) {
228             URLInfo info = getInfo( url );
229             if ( info == null ) {
230                 register( new URLInfo( url, status, message ) );
231             } else {
232                 info.setStatus( status );
233                 info.setMessage( message );
234             }
235         }
236     }
237
238     /**
239      * Register or replace an URL record. All records are keyed to
240      * the imutable URL of URLInfo.
241      *
242      * @param info the info record to store
243      */

244     public void register( URLInfo info ) {
245         if ( info != null) {
246             synchronized (urls) {
247                 if( getInfo( info.getURL() ) == null )
248                     urls.put( info.getURL().intern(), info );
249             }
250         }
251     }
252
253     /**
254      * Unregister an URL from the repository
255      *
256      * @param url the url to remove
257      */

258     public void unregister( String JavaDoc url ) {
259         if ( url != null ) {
260             synchronized (urls) {
261                 urls.remove( url.intern() );
262             }
263         }
264     }
265
266     /**
267      * Get the information record stored in the database about
268      * an URL.
269      *
270      * @param url the url whose record is sought
271      * @return the description record found in the repository or null.
272      */

273     public URLInfo getInfo( String JavaDoc url ) {
274         URLInfo info = null;
275
276         if ( url != null ) {
277             synchronized(urls) {
278                 info = (URLInfo)urls.get( url.intern() );
279             }
280         }
281
282         return info;
283     }
284
285     /**
286      * Test whether the URL is currently believed to be OK by this
287      * repository.
288      *
289      * @param url the url to be tested
290      * @return false is the url is known by this repository and has
291      * a status indicating an error, true otherwise.
292      */

293     public boolean isOK( String JavaDoc url ) {
294         URLInfo info = getInfo( url );
295
296         // we don't know this URL, play it safe and say it's good
297
if ( info == null ) return true;
298
299         return ( info.getStatus() == URLManagerService.STATUS_OK );
300     }
301
302     /**
303      * List of the current known URLs in the repository
304      *
305      * @return a List of URL strings known to this repository
306      */

307     public List JavaDoc list() {
308         synchronized (urls) {
309             return new Vector JavaDoc( urls.keySet() );
310         }
311     }
312
313     /**
314      * List of the current known URLs in the repository which have
315      * the given status.
316      *
317      * @param status the status to be retrieved. May be
318      * {@link URLManagerService#STATUS_ANY} to indicate any status
319      * @return a List of URL strings known to this repository with this status
320      */

321     public List JavaDoc list( int status ) {
322         Vector JavaDoc result = new Vector JavaDoc();
323
324         synchronized (urls) {
325             Iterator JavaDoc i = urls.entrySet().iterator();
326             while( i.hasNext() ) {
327                 Map.Entry JavaDoc entry = (Map.Entry JavaDoc)i.next();
328                 URLInfo info = (URLInfo)entry.getValue();
329                 if ( ( info.getStatus() & status ) != 0 ) {
330                     result.addElement( entry.getKey() );
331                 }
332             }
333         }
334
335         return result;
336     }
337
338     /**
339      * Load the persisted state of the repository from disk
340      */

341     private synchronized void load() {
342
343         Map JavaDoc store = new HashMap JavaDoc();
344         Configuration config = null;
345
346         logger.info( "Restoring the URLs from disk: " + path );
347
348         try {
349             config = new Configuration( path );
350
351             int count = 1;
352             String JavaDoc url = null;
353
354             while ( ( url = ( config
355                               .getString("entry."+count+".url") ) ) != null ) {
356                 //Intern the url to ensure we can use "==" to compare
357
//and synchronize on it
358
url = url.intern();
359                 int status = config.getInteger("entry."+count+".status", URLManagerService.STATUS_OK );
360                 if( store.get( url ) == null )
361                     store.put( url, new URLInfo( url, status ) );
362                 count++;
363             }
364
365             logger.info( "URLManager loaded " + count + " urls" );
366
367         } catch ( Exception JavaDoc e ) {
368             logger.error( "Could not restore URLManager state", e );
369             return;
370         } finally {
371             // set the loaded store as the new store
372
this.urls = store;
373         }
374
375     }
376
377     /**
378      * Persist the state of the repository on disk in a properties file
379      */

380     private synchronized void save() {
381         PrintWriter JavaDoc pw = null ;
382
383         try {
384
385             File JavaDoc propfile = new File JavaDoc(path); // FileWriter doesn't always do this
386
propfile.getParentFile().mkdirs();
387             propfile.createNewFile();
388
389             pw = new PrintWriter JavaDoc( new BufferedWriter JavaDoc( new FileWriter JavaDoc( propfile ) ) );
390             synchronized (urls) {
391                 Iterator JavaDoc i = urls.values().iterator();
392                 int entryNum = 1;
393                 while( i.hasNext() ) {
394                     URLInfo info = (URLInfo)i.next();
395                     pw.print( "entry." );
396                     pw.print( entryNum );
397                     pw.print( ".url=" );
398                     writeEscaped( pw, info.getURL() );
399                     pw.println( "" );
400                     pw.print( "entry." );
401                     pw.print( entryNum );
402                     pw.print( ".status=" );
403                     pw.print( info.getStatus() );
404                     pw.println( "" );
405                     entryNum++;
406                 }
407             }
408         }
409         catch ( Throwable JavaDoc t )
410         {
411             logger.error( "Impossible to save URLManager state to "+path, t );
412         }
413         finally
414         {
415             if( pw != null )
416             {
417                 pw.close();
418             }
419         }
420     }
421
422     /**
423      * Return the port of a proxy
424      * @param protocol The protocol that the proxy supports, e.g. 'http'
425      * @return The port number (1-65535), or -1 if no port was specified (= use default)
426      */

427     public int getProxyPort( String JavaDoc protocol ) {
428         Integer JavaDoc proxyPort = (Integer JavaDoc)proxies.get( (protocol + ".port").toLowerCase() );
429
430         if (proxyPort != null)
431             return proxyPort.intValue();
432         else
433             return -1;
434     }
435
436     /**
437      * Return a proxy's hostname
438      * @param protocol The protocol that the proxy supports, e.g. 'http'
439      * @return The hostname of the proxy, or <code>null</code> if no proxy is specified for this protocol
440      */

441     public String JavaDoc getProxyHost( String JavaDoc protocol ) {
442         String JavaDoc proxyHost = (String JavaDoc)proxies.get( (protocol + ".host").toLowerCase() );
443
444         return proxyHost;
445     }
446
447     /**
448      * <p>Escape values when saving.
449      * Appends a String to a StringBuffer, escaping commas.</p>
450      * <p>We assume that commas are unescaped.</p>
451      * @param sink a StringBuffer to write output
452      * @param element a value to be written
453      */

454     protected void writeEscaped( PrintWriter JavaDoc sink, String JavaDoc element ) {
455         int upTo = element.indexOf(",");
456         if( upTo == -1 ) {
457             sink.print( element );
458             return;
459         }
460         sink.print( element.substring( 0, upTo ) );
461         sink.print( "\\," );
462         writeEscaped( sink, element.substring( upTo+1, element.length() ) );
463         return;
464     }
465 }
466
Popular Tags