KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > admin > event > ElementChangeHelper


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 package com.sun.enterprise.admin.event;
25
26 import java.lang.reflect.Constructor JavaDoc;
27
28 import java.util.ArrayList JavaDoc;
29 import java.util.Set JavaDoc;
30 import java.util.HashSet JavaDoc;
31 import java.util.Iterator JavaDoc;
32 import com.sun.enterprise.admin.event.AdminEvent;
33 import com.sun.enterprise.config.ConfigContext;
34 import com.sun.enterprise.config.ConfigChange;
35 import com.sun.enterprise.config.ConfigAdd;
36 import com.sun.enterprise.config.ConfigSet;
37 import com.sun.enterprise.config.ConfigUpdate;
38 import com.sun.enterprise.config.ConfigDelete;
39 import com.sun.enterprise.config.serverbeans.ServerTags;
40
41 import com.sun.enterprise.admin.meta.MBeanRegistry;
42 import com.sun.enterprise.admin.meta.MBeanRegistryFactory;
43 import com.sun.enterprise.admin.meta.MBeanRegistryEntry;
44 import com.sun.enterprise.admin.meta.naming.MBeanNamingDescriptor;
45 import com.sun.enterprise.admin.target.Target;
46 import com.sun.enterprise.admin.target.TargetBuilder;
47
48 //i18n import
49
import com.sun.enterprise.util.i18n.StringManager;
50
51 /**
52  * Config Element Change Helper - class providing ElementChangeEvent
53  * related services (events constructing/ change lists filtering etc.
54  *
55  */

56 public class ElementChangeHelper{
57
58     /**
59      * Event type
60      */

61     static final String JavaDoc eventType = ElementChangeHelper.class.getName();
62
63     // i18n StringManager
64
private static StringManager localStrings = StringManager.getManager( ElementChangeHelper.class );
65     private static String JavaDoc PROPERTY_SUBSTR = "/"+ServerTags.ELEMENT_PROPERTY+"[";
66     
67     //**********************************************************************
68
public ElementChangeHelper()
69     {
70     }
71
72     //**********************************************************************
73
static boolean isChangesToMerge(ConfigChange change1, ConfigChange change2)
74     {
75         String JavaDoc xpath1, xpath2;
76         if( change1==null || change2==null ||
77             (xpath1 = change1.getXPath())==null ||
78             (xpath2 = change2.getXPath())==null ||
79             !compareXPathes( xpath1, xpath2) )
80             return false;
81         if(isPropertyXPath(xpath2)) //optimize it later
82
return true;
83         return ( xpath1.equals(change2.getXPath()) &&
84             change1.getClass().equals(change2.getClass()) );
85     }
86     
87     //***************************************************************************
88
static boolean checkChangeListForElement(ArrayList JavaDoc list)
89     {
90         if(list==null || list.size()<=0)
91             return false;
92         for(int i=1; i<list.size(); i++)
93             if(!isChangesToMerge((ConfigChange)list.get(i-1), (ConfigChange)list.get(i)))
94                return false;
95         return true;
96     }
97     //***************************************************************************
98
static boolean isPropertyChange(ConfigChange change)
99     {
100         String JavaDoc xpath;
101         return (change!=null &&
102                 (xpath = change.getXPath())!=null &&
103                 (xpath.indexOf(PROPERTY_SUBSTR))>=0 );
104     }
105     //***************************************************************************
106
static boolean isPropertyXPath(String JavaDoc xpath)
107     {
108         return ((xpath != null) && ((xpath.indexOf(PROPERTY_SUBSTR))>=0));
109     }
110     //***************************************************************************
111
// getting the primary key of config element
112
static String JavaDoc getConfigElementPrimaryKey(String JavaDoc xpath)
113     {
114         if (xpath != null) {
115             xpath = xpath.trim();
116         }
117         if((xpath!= null) && (xpath.endsWith("']")))
118         {
119             int idx = xpath.lastIndexOf('\'', xpath.length()-3);
120             return xpath.substring(idx+1, xpath.length()-2);
121         }
122         return null;
123     }
124
125     //***************************************************************************
126
// getting the type of config element
127
static String JavaDoc getConfigElementType(String JavaDoc xpath)
128     {
129         if(xpath.trim().endsWith("]"))
130             xpath = xpath.substring(0, xpath.lastIndexOf('['));
131         return xpath.substring(0, xpath.lastIndexOf('/'));
132     }
133
134     //***************************************************************************
135
// get target name for event
136
static String JavaDoc getConfigElementTargetName(String JavaDoc xpath, ConfigContext ctx)
137     {
138         String JavaDoc targetName = null;
139         try {
140             // Get target name for event
141
TargetBuilder targetBuilder = new TargetBuilder();
142             return targetBuilder.getTargetNameForXPath(xpath, ctx, true);
143         } catch(Exception JavaDoc e)
144         {
145             //can not find target -> get default (domain)
146
}
147         return null;
148     }
149     //***************************************************************************
150
static String JavaDoc getElementXPath(ArrayList JavaDoc changes)
151     {
152         return getElementXPath((ConfigChange)changes.get(0));
153     }
154     
155     static String JavaDoc getElementXPath(ConfigChange change)
156     {
157         String JavaDoc xpath = change.getXPath();
158         if(xpath==null)
159             return xpath;
160         int iMatch = xpath.indexOf(PROPERTY_SUBSTR);
161         if(iMatch<0)
162             return xpath;
163         return xpath.substring(0, iMatch);
164     }
165     //***************************************************************************
166
static int getActionCodeForChanges(ArrayList JavaDoc changes)
167     {
168         return getActionCodeForChange((ConfigChange)changes.get(0));
169     }
170     
171     static int getActionCodeForChange(ConfigChange change)
172     {
173         if(isPropertyXPath(change.getXPath()))
174             return ElementChangeEvent.ACTION_ELEMENT_UPDATE;
175         int action;
176     //set action code
177
if(change instanceof ConfigSet)
178             action = ElementChangeEvent.ACTION_ELEMENT_CREATE;
179         else if(change instanceof ConfigAdd)
180             action = ElementChangeEvent.ACTION_ELEMENT_CREATE;
181         else if(change instanceof ConfigUpdate)
182             action = ElementChangeEvent.ACTION_ELEMENT_UPDATE;
183         else if(change instanceof ConfigDelete)
184             action = ElementChangeEvent.ACTION_ELEMENT_DELETE;
185         else
186             action = ElementChangeEvent.ACTION_ELEMENT_UNDEFINED;
187         return action;
188     }
189     
190     //***************************************************************************
191
static private boolean compareXPathes(String JavaDoc xpath1, String JavaDoc xpath2)
192     {
193         int iProp;
194         if((iProp = xpath1.indexOf(PROPERTY_SUBSTR))>0)
195             xpath1 = xpath1.substring(0, iProp);
196         if((iProp = xpath2.indexOf(PROPERTY_SUBSTR))>0)
197             xpath2 = xpath2.substring(0, iProp);
198         return xpath1.equals(xpath2);
199     }
200
201     /*
202      * generate the array of ElementChangeEvents from given change list
203      * @param changeList list of ConfigChanges to analyse
204      * @param domainContext ConfigContext of domaiin.xml config file
205      * @returns array of ElementChangeEvents
206      * @throws IllegalArgumentException
207      */

208     public AdminEvent[] generateElementChangeEventsFromChangeList(String JavaDoc instanceName, ArrayList JavaDoc changeList, ConfigContext domainContext)
209     {
210         ArrayList JavaDoc merged = new ArrayList JavaDoc();
211         ArrayList JavaDoc events = new ArrayList JavaDoc();
212         ConfigChange change, lastChange = null;
213         for(int i=0; i<changeList.size(); i++)
214         {
215             change = (ConfigChange)changeList.get(i);
216             if(merged.isEmpty() ||
217                isChangesToMerge(lastChange, change))
218             {
219                 //add change to list
220
merged.add(change);
221                 lastChange = change;
222             }
223             else
224             {
225                 //here we are only if collected changes portion completed
226
// it is time to create ElementChangeEvent
227
if(!merged.isEmpty())
228                 {
229                     ArrayList JavaDoc new_events = createEventsForElementChange(instanceName, merged, domainContext, changeList);
230                     if(new_events!=null && new_events.size()>0)
231                         events.addAll(new_events);
232                     //FIXME: - do we need treat empty answer as "restart is needed" sign?
233
merged.clear();
234                     //add change to list
235
merged.add(change);
236                     lastChange = change;
237                 }
238             }
239         }
240         // last portion could be here
241
if(!merged.isEmpty())
242         {
243             ArrayList JavaDoc new_events = createEventsForElementChange(instanceName, merged, domainContext, changeList);
244             if(new_events!=null && new_events.size()>0)
245                 events.addAll(new_events);
246             //FIXME: - do we need treat empty answer as "restart is needed" sign?
247
}
248         return (AdminEvent[])events.toArray(new AdminEvent[events.size()]);
249     }
250
251     /*
252      * create ElementChangeEvents from given change list
253      * (all changes should be related to the same element)
254      * @param changeList list of ConfigChanges related to the same element
255      * @param domainContext ConfigContext of domaiin.xml config file
256      * @returns array of ElementChangeEvent (or null)
257      * @throws IllegalArgumentException
258      */

259     public ArrayList JavaDoc createEventsForElementChange(String JavaDoc instanceName, ArrayList JavaDoc changeList, ConfigContext domainContext, ArrayList JavaDoc globalChangeList)
260     {
261        return createEventsForElementChange(instanceName, changeList, domainContext, true, globalChangeList);
262     }
263     
264     private ArrayList JavaDoc createEventsForElementChange(String JavaDoc instanceName, ArrayList JavaDoc changeList, ConfigContext domainContext, boolean bCheckList, ArrayList JavaDoc globalChangeList)
265     {
266         
267         if(bCheckList && !checkChangeListForElement(changeList))
268         {
269             String JavaDoc msg = localStrings.getString( "admin.event.wrong_configchange" );
270             throw new IllegalArgumentException JavaDoc( msg );
271         }
272
273         String JavaDoc xpath0 = getElementXPath(changeList);
274         if(xpath0==null)
275             return null;
276         // instantiate the proper Event
277
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
278
// 1. get event name
279

280         MBeanRegistryEntry entry = getRegistryEntry(xpath0);
281         if(entry==null)
282             return null;
283
284         String JavaDoc eventName = entry.getElementChangeEventName();
285         if(eventName!=null && eventName.indexOf('.')<0)
286             eventName = EVENT_PACKAGE_PATH_PREFIX + eventName;
287         if(eventName==null)
288             return null; //element is not a subject for ElementChangeEvent
289

290         // 2. instantiate event
291
try {
292            return ElementChangeEventsFactory.createEvents(eventName, instanceName,
293                       entry.getName(), changeList, domainContext, globalChangeList);
294         } catch(Exception JavaDoc e)
295         {
296             e.printStackTrace();
297             String JavaDoc msg = localStrings.getString( "admin.event.cannot_create_eventforchange", eventName, xpath0 );
298             throw new IllegalArgumentException JavaDoc( msg );
299         }
300     }
301
302     
303     String JavaDoc lastXpath = null;
304     MBeanRegistryEntry lastEntry = null;
305     static final public String JavaDoc EVENT_PACKAGE_PATH_PREFIX = "com.sun.enterprise.admin.event.";
306     
307     private synchronized MBeanRegistryEntry getRegistryEntry(String JavaDoc xpath)
308     {
309         if(xpath.equals(lastXpath))
310             return lastEntry;
311         MBeanRegistry registry = MBeanRegistryFactory.getAdminMBeanRegistry();
312         MBeanRegistryEntry entry = registry.findMBeanRegistryEntryByXPath(xpath);
313         if(entry!=null)
314         {
315             lastXpath = xpath;
316             lastEntry = entry;
317         }
318         return entry;
319     }
320
321     static public Set JavaDoc getXPathesForDynamicallyNotReconfigurableElements(ArrayList JavaDoc changeList)
322     {
323         HashSet JavaDoc xpathes = new HashSet JavaDoc();
324         if(changeList==null)
325             return xpathes;
326
327         MBeanRegistry registry = MBeanRegistryFactory.getAdminMBeanRegistry();
328         String JavaDoc xpath_last = null;
329         MBeanRegistryEntry entry = null;
330         boolean bLastEntryHasEvent = false;
331         String JavaDoc propertyName = null;
332         
333         for(int i=0; i<changeList.size();i++)
334         {
335             ConfigChange change = (ConfigChange)changeList.get(i);
336             int action = getActionCodeForChange(change);
337             if(action==ElementChangeEvent.ACTION_ELEMENT_UNDEFINED)
338                 continue; //??? not add/set/update/delete
339
String JavaDoc xpath = change.getXPath();
340             // Check if this xpath belongs to one of the excluded
341
// XPaths. Excluded xpaths include lb-configs, lb-config
342
// etc. Where restart checks do not apply.
343
if ( (xpath == null) || isXPathExcludedForRestartCheck(xpath) ) {
344                 continue;
345             }
346             if(!xpath.equals(xpath_last))
347             {
348                 xpath_last = xpath;
349                 if(isPropertyXPath(change.getXPath()))
350                 {
351                     propertyName = getConfigElementPrimaryKey(xpath);
352                     xpath = getElementXPath(change);
353                 }
354                 else
355                 {
356                     propertyName = null;
357                 }
358                 entry = registry.findMBeanRegistryEntryByXPath(xpath);
359                 if(entry==null)
360                 {
361                     xpathes.add(xpath);
362                     continue;
363                 }
364                 bLastEntryHasEvent = (entry.getElementChangeEventName()!=null);
365             }
366             if(bLastEntryHasEvent)
367                 continue;
368             // check whether creation reconfigurable
369
if( (action==ElementChangeEvent.ACTION_ELEMENT_CREATE &&
370                  entry.isElementCreationDynamicallyReconfigurable()))
371             {
372                 xpathes.add(xpath);
373                 continue;
374             }
375             // check whether deletion reconfigurable
376
if( (action==ElementChangeEvent.ACTION_ELEMENT_DELETE &&
377                  entry.isElementDeletionDynamicallyReconfigurable()))
378             {
379                 xpathes.add(xpath);
380                 continue;
381             }
382             // check properties changes
383
if(propertyName!=null)
384             {
385                 if(!entry.isPropertyDynamicallyReconfigurable(propertyName))
386                 {
387                     xpathes.add(xpath);
388                     continue;
389                 }
390             }
391             if ( !(change instanceof ConfigUpdate))
392             {
393                 xpathes.add(xpath);
394                 continue;
395             }
396             //here we are only for attributes
397
Set JavaDoc attrs = ((ConfigUpdate)change).getAttributeSet();
398             Iterator JavaDoc iter = attrs.iterator();
399             while(iter.hasNext())
400             {
401                 String JavaDoc attr = (String JavaDoc)iter.next();
402                 if(!entry.isAttributeDynamicallyReconfigurable(attr))
403                 {
404                     xpathes.add(xpath);
405                     break;
406                 }
407             }
408         }
409         return xpathes;
410     }
411
412     /**
413      * Get a boolean value corresponding to the string value in xml.
414      * @param strValue the string representing a boolean
415      * @return true if the string is "true", "yes", "on" or "1"
416      */

417     public static boolean getBooleanValue(String JavaDoc strValue) {
418         boolean retval = false;
419         if (strValue == null) {
420             return retval;
421         }
422         if (strValue.equalsIgnoreCase("true")
423                 || strValue.equalsIgnoreCase("yes")
424                 || strValue.equalsIgnoreCase("on")
425                 || strValue.equalsIgnoreCase("1")) {
426             retval = true;
427         }
428         return retval;
429     }
430     
431     /**
432      * Checks if an XPath is excluded for restart required check.
433      * Restart required check is skipped for lb-configs and lb-config
434      * elements.
435      *
436      * @param xpath XPath of the config change
437      *
438      * @return boolean true - if restart required check to be ignored, false
439      * otherwise
440      */

441     private static boolean isXPathExcludedForRestartCheck(String JavaDoc xpath)
442     {
443         if (xpath == null) {
444             return false;
445         }
446
447         for(int excludeIdx =0; excludeIdx < restartExcludeXPaths.length;
448                 excludeIdx++) {
449
450             if ( xpath.startsWith(restartExcludeXPaths[excludeIdx]) ) {
451                 return true;
452             }
453         }
454         return false;
455     }
456
457     /*
458      * finds "enabled" update element in change-list and returns its new value (as Boolean)
459      * or null if not found
460      */

461     public static Boolean JavaDoc findEnabledChange(ArrayList JavaDoc changeList)
462     {
463         if(changeList==null)
464             return null;
465         for(int i=changeList.size()-1; i>=0; i--)
466         {
467             if ( changeList.get(i) instanceof ConfigUpdate)
468                 {
469                     ConfigUpdate update = (ConfigUpdate)changeList.get(i);
470                     String JavaDoc enableStr = update.getNewValue(ServerTags.ENABLED);
471                     if (enableStr != null)
472                         return new Boolean JavaDoc(ElementChangeHelper.getBooleanValue(enableStr));
473                 }
474         }
475         return null;
476     }
477
478     // PRIVATE VARIABLES
479

480     // The XPath prefixes are excluded during restart required check.
481
// These XPaths belong to lb-configs and lb-config element
482

483     private static String JavaDoc[] restartExcludeXPaths = { "/domain/lb-configs" };
484 }
485
Popular Tags