KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > excalibur > instrument > client > http > HTTPInstrumentManagerConnection


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

19
20 package org.apache.excalibur.instrument.client.http;
21
22 import java.io.InputStream JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.io.UnsupportedEncodingException JavaDoc;
25 import java.net.HttpURLConnection JavaDoc;
26 import java.net.MalformedURLException JavaDoc;
27 import java.net.URL JavaDoc;
28 import java.net.URLEncoder JavaDoc;
29 import java.util.ArrayList JavaDoc;
30 import java.util.List JavaDoc;
31
32 import org.apache.avalon.framework.configuration.Configuration;
33 import org.apache.avalon.framework.configuration.ConfigurationException;
34 import org.apache.avalon.framework.configuration.DefaultConfiguration;
35 import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
36 import org.apache.avalon.framework.logger.AbstractLogEnabled;
37 import org.apache.avalon.framework.logger.Logger;
38
39 import org.apache.excalibur.instrument.client.InstrumentableData;
40 import org.apache.excalibur.instrument.client.InstrumentManagerConnection;
41 import org.apache.excalibur.instrument.client.InstrumentManagerConnectionListener;
42 import org.apache.excalibur.instrument.client.InstrumentManagerData;
43 import org.apache.excalibur.instrument.client.InstrumentSampleFrame;
44
45 /**
46  * A Connection to the remote InstrumentManager which connects using
47  * the HTTP connector.
48  *
49  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
50  * @version CVS $Revision: 1.4 $ $Date: 2004/02/28 11:47:23 $
51  * @since 4.1
52  */

53 public class HTTPInstrumentManagerConnection
54     extends InstrumentManagerConnection
55 {
56     private URL JavaDoc m_url;
57     
58     /** Flag which keeps track of whether or not the remote server was there
59     * the last time we attempted to connect. */

60     private boolean m_connected;
61     
62     /** If we ever decide that we are not talking to an Instrument Manager then
63      * disable the connection to avoid pounding the remote server with lots
64      * of 404 requests. */

65     private boolean m_disabled;
66     
67     private HTTPInstrumentManagerData m_manager;
68     
69     private List JavaDoc m_leasedSamples = new ArrayList JavaDoc();
70     private HTTPInstrumentSampleData[] m_leasedSampleAry;
71
72     /*---------------------------------------------------------------
73      * Constructors
74      *-------------------------------------------------------------*/

75     /**
76      * Creates a new HTTPInstrumentManagerConnection.
77      */

78     public HTTPInstrumentManagerConnection( URL JavaDoc url )
79     {
80         m_url = url;
81         m_connected = false;
82         
83         m_manager = new HTTPInstrumentManagerData( this );
84     }
85     
86     /*---------------------------------------------------------------
87      * InstrumentManagerConnection Methods
88      *-------------------------------------------------------------*/

89     public void enableLogging( Logger logger )
90     {
91         super.enableLogging( logger );
92         m_manager.enableLogging( logger.getChildLogger( "manager" ) );
93     }
94     
95     /**
96      * Returns the key used to identify this object.
97      *
98      * @return The key used to identify this object.
99      */

100     public Object JavaDoc getKey()
101     {
102         return m_url;
103     }
104     
105     /**
106      * Returns true if connected.
107      *
108      * @return True if connected.
109      */

110     public boolean isConnected()
111     {
112         return m_connected;
113     }
114     
115     /**
116      * Returns the Instrument Manager.
117      *
118      * @return The Instrument Manager.
119      */

120     public InstrumentManagerData getInstrumentManager()
121     {
122         return m_manager;
123     }
124     
125     /**
126      * Returns the title to display in the tab for the connection.
127      *
128      * @return The tab title.
129      */

130     public String JavaDoc getTabTitle()
131     {
132         if ( m_disabled )
133         {
134             return "[DISABLED] " + super.getTabTitle();
135         }
136         else
137         {
138             return super.getTabTitle();
139         }
140     }
141
142     /**
143      * Invokes GC on the JVM running the InstrumentManager.
144      */

145     protected void invokeGC()
146     {
147         getState( "gc.xml" );
148     }
149
150     /**
151      * Saves the current state into a Configuration.
152      *
153      * @return The state as a Configuration.
154      */

155     public Configuration saveState()
156     {
157         synchronized( this )
158         {
159             DefaultConfiguration state = (DefaultConfiguration)super.saveState();
160             
161             state.setAttribute( "url", m_url.toExternalForm() );
162             
163             return state;
164         }
165     }
166
167     /**
168      * Loads the state from a Configuration object.
169      *
170      * @param state Configuration object to load state from.
171      *
172      * @throws ConfigurationException If there were any problems loading the
173      * state.
174      */

175     public void loadState( Configuration state )
176         throws ConfigurationException
177     {
178         synchronized( this )
179         {
180             super.loadState( state );
181             
182             // URL will have already been set.
183
}
184     }
185     
186     /**
187      * URL encode the specified string.
188      *
189      * @param val String to be URL encoded.
190      *
191      * @return The URL encoded string.
192      */

193     String JavaDoc urlEncode( String JavaDoc val )
194     {
195         try
196         {
197             return URLEncoder.encode( val, "UTF8" );
198         }
199         catch ( UnsupportedEncodingException JavaDoc e )
200         {
201             // Should never happen.
202
getLogger().error( "Bad encoding.", e );
203             return val;
204         }
205     }
206     
207     /**
208      * Updates all registered SampleFrames with the latest data from the
209      * server. The status of all Sample Frames is also handled by this
210      * method, so it must handle disconnected connections and missing or
211      * expired samples correctly.
212      *
213      * This method overrides the default to implement a batch update to
214      * get all snapshots from the server in a single request.
215      */

216     public void updateSampleFrames()
217     {
218         InstrumentSampleFrame[] frames = getSampleFrameArray();
219         if ( frames.length == 0 )
220         {
221             // Nothing to do.
222
return;
223         }
224         
225         // Build up a set of arrays so that all of the snapshots can be requested at once.
226
String JavaDoc[] names = new String JavaDoc[frames.length];
227         long[] lastTimes = new long[frames.length];
228         HTTPInstrumentSampleSnapshotData[] snapshots =
229             new HTTPInstrumentSampleSnapshotData[frames.length];
230         for ( int i = 0; i < frames.length; i++ )
231         {
232             InstrumentSampleFrame frame = frames[i];
233             names[i] = frame.getInstrumentSampleName();
234             lastTimes[i] = frame.getLastSnapshotTime();
235         }
236         
237         // Request the snapshots. Don't bother if we know we are not connected.
238
if ( isConnected() )
239         {
240             StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
241             sb.append( "snapshots.xml?packed=true&compact=true" );
242             for ( int i = 0; i < frames.length; i++ )
243             {
244                 sb.append( "&name=" );
245                 sb.append( this.urlEncode( names[i] ) );
246                 sb.append( "&base-time=" );
247                 sb.append( lastTimes[i] );
248             }
249             Configuration configuration = getState( sb.toString() );
250             if ( configuration != null )
251             {
252                 Configuration[] snapshotConfs = configuration.getChildren( "sample" );
253                 for ( int i = 0; i < snapshotConfs.length; i++ )
254                 {
255                     Configuration snapshotConf = snapshotConfs[i];
256                     String JavaDoc name = snapshotConf.getAttribute( "name", null );
257                     if ( name != null )
258                     {
259                         boolean expired = snapshotConf.getAttributeAsBoolean( "expired", false );
260                         if ( !expired )
261                         {
262                             // Look for the specified sample frame. Should always exist.
263
for ( int j = 0; j < frames.length; j++ )
264                             {
265                                 if ( name.equals( names[j] ) )
266                                 {
267                                     snapshots[j] =
268                                         new HTTPInstrumentSampleSnapshotData( this, name );
269                                     snapshots[j].enableLogging( getLogger() );
270                                     try
271                                     {
272                                         snapshots[j].update( snapshotConf );
273                                     }
274                                     catch ( ConfigurationException e )
275                                     {
276                                         // Should not happen.
277
getLogger().info( "Snapshot update failed.", e );
278                                         getLogger().info( " URL: " + sb.toString() );
279                                         getLogger().info( " i:" + i + " j:" + j );
280                                         snapshots[j] = null;
281                                     }
282                                     break;
283                                 }
284                             }
285                         }
286                     }
287                 }
288             }
289         }
290         
291         // Now we should have all available snapshots. Loop back over the frames
292
// and update them as is appropriate.
293
for ( int i = 0; i < frames.length; i++ )
294         {
295             InstrumentSampleFrame frame = frames[i];
296             frame.updateSnapshot( snapshots[i] );
297         }
298     }
299     
300     /*---------------------------------------------------------------
301      * Methods
302      *-------------------------------------------------------------*/

303     /**
304      * Returns the URL of the remote InstrumentManager.
305      *
306      * @return The URL of the remote InstrumentManager.
307      */

308     URL JavaDoc getURL()
309     {
310         return m_url;
311     }
312     
313     /**
314      * Requests the current state of the object at the specified path.
315      * If the request fails for any reason, including not being valid
316      * content then the method will return null.
317      *
318      * @param path The path of the object whose state is requested.
319      *
320      * @return The state as a Configuration object, or null if it failed.
321      */

322     Configuration getState( String JavaDoc path )
323     {
324         if ( m_disabled )
325         {
326             return null;
327         }
328         
329         URL JavaDoc url;
330         try
331         {
332             url = new URL JavaDoc( m_url, path );
333         }
334         catch ( MalformedURLException JavaDoc e )
335         {
336             getLogger().debug( "Request failed.", e );
337             return null;
338         }
339         
340         try
341         {
342             HttpURLConnection JavaDoc conn = (HttpURLConnection JavaDoc)url.openConnection();
343             
344             if ( conn.getResponseCode() == conn.HTTP_OK )
345             {
346                 boolean oldConnected = m_connected;
347                 m_connected = true;
348                 if ( !oldConnected )
349                 {
350                     // Notify the listeners.
351
InstrumentManagerConnectionListener[] listenerArray = getListenerArray();
352                     for ( int i = 0; i < listenerArray.length; i++ )
353                     {
354                         listenerArray[i].opened( this );
355                     }
356                 }
357                 
358                 InputStream JavaDoc is = conn.getInputStream();
359                 try
360                 {
361                     DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
362                     try
363                     {
364                         return builder.build( is );
365                     }
366                     catch ( ConfigurationException e )
367                     {
368                         getLogger().warn( "Invalid XML reveived from the server.", e );
369                         return null;
370                     }
371                     catch ( org.xml.sax.SAXException JavaDoc e )
372                     {
373                         getLogger().warn( "Invalid XML reveived from the server.", e );
374                         return null;
375                     }
376                 }
377                 finally
378                 {
379                     is.close();
380                 }
381             }
382             else
383             {
384                 if ( ( conn.getResponseCode() == 404 )
385                     && path.startsWith( "instrument-manager.xml" ) )
386                 {
387                     getLogger().warn( "Requested " + url + " resulted in error code 404. "
388                         + "Most likely not an Instrument Manager, disabling future requests." );
389                     m_disabled = true;
390                 }
391                 else
392                 {
393                     getLogger().debug( "Response: " + conn.getResponseCode() + " : "
394                         + conn.getResponseMessage() );
395                 }
396                 return null;
397             }
398         }
399         catch ( IOException JavaDoc e )
400         {
401             String JavaDoc msg = e.getMessage();
402             if ( msg == null )
403             {
404                 msg = e.toString();
405             }
406             
407             if ( msg.indexOf( "Connect" ) >= 0 )
408             {
409                 // Hide the stack trace as the server is simply down.
410
getLogger().debug( "Request failed. URL: " + url + " Error: " + msg );
411             }
412             else
413             {
414                 getLogger().debug( "Request failed. URL: " + url + " Error: ", e );
415             }
416             
417             
418             boolean oldConnected = m_connected;
419             m_connected = false;
420             if ( oldConnected )
421             {
422                 // Notify the listeners.
423
InstrumentManagerConnectionListener[] listenerArray = getListenerArray();
424                 for ( int i = 0; i < listenerArray.length; i++ )
425                 {
426                     listenerArray[i].closed( this );
427                 }
428             }
429             
430             return null;
431         }
432     }
433 }
Popular Tags