KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > config > serverbeans > validation > XPathHelper


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.config.serverbeans.validation;
25
26 //jdk imports
27
import java.util.ArrayList JavaDoc;
28 import java.util.StringTokenizer JavaDoc;
29 import java.text.CharacterIterator JavaDoc;
30 import java.text.StringCharacterIterator JavaDoc;
31
32 import com.sun.enterprise.util.LocalStringManagerImpl;
33
34 // config imports
35
import com.sun.enterprise.config.ConfigContext;
36 import com.sun.enterprise.config.ConfigException;
37 import com.sun.enterprise.config.ConfigBean;
38 import com.sun.enterprise.config.serverbeans.*;
39
40 //JMX
41
import javax.management.Attribute JavaDoc;
42 import javax.management.AttributeList JavaDoc;
43
44 /**
45  * This class provides helper methods for xpath handling in ConfigBeans space
46  *
47  * $Id: XPathHelper.java,v 1.3 2005/12/25 03:44:26 tcfujii Exp $
48  * @author alexkrav
49  *
50  * $Log: XPathHelper.java,v $
51  * Revision 1.3 2005/12/25 03:44:26 tcfujii
52  * Updated copyright text and year.
53  *
54  * Revision 1.2 2005/06/27 21:18:17 tcfujii
55  * Issue number: CDDL header updates.
56  *
57  * Revision 1.1 2005/06/17 17:09:58 kravtch
58  * MS3: Config Validator's infrastructure changes:
59  * - new "VALIDATE" ConfigContextEvent type introduced for "static" validation;
60  * - host "static" validation as ConfigContext listener for "VALIDATE" events;
61  * - new namespace "http://www.sun.com/ias/validation" support for RelaxNG schemas extension:
62  * - "name-domains" metadata support for test uniquiness/references;
63  * - new "belongs-to"/"references-to"/"type"/"**-than" schema attributes;
64  * - most rng element definitions and xslt scripts changed;
65  * - new base validation classes to perform generic validation;
66  * - custom validation test classes cleaned from performing generic validation cases;
67  * - ConfigBeans and domain dtd re-generated;
68  * - Schematron(scripts and validation) and Relax NG (validator only) not used for validation any more;
69  * Submitted by: kravtch
70  * Tests passed QLT/EE + devtests
71  * Modules affected: appserver-commons; admin/validator; admin-core/config-api
72  *
73 */

74
75 public abstract class XPathHelper {
76     
77     /**
78      * This method returns number of elements in given xpath (depth)
79      *
80      **/

81     public static int getNumberOfElemTokens(String JavaDoc xpath)
82     {
83         int[] cuts = getElemDelimitersPositions(xpath);
84         int iTokens = cuts.length;
85         if(iTokens>0 && cuts[0]==0)
86             iTokens--;
87         if(cuts.length>0 && cuts[cuts.length-1]<xpath.length()-1)
88            iTokens++;
89         return iTokens;
90     }
91
92     public static String JavaDoc getXPathPrefix(String JavaDoc xpath, int numberOfTokensInPrefix)
93     {
94         if(numberOfTokensInPrefix<=0)
95             return "";
96         int[] cuts = getElemDelimitersPositions(xpath);
97         int delimIdx = numberOfTokensInPrefix;
98 //System.out.println("$$getXPathPrefix() xpath="+xpath + " numberOfTokensInPrefix=" + numberOfTokensInPrefix);
99
if(cuts.length>0 && cuts[0]!=0)
100             delimIdx--;
101         if(delimIdx<cuts.length)
102             return xpath.substring(0, cuts[delimIdx]);
103         if(delimIdx==cuts.length && cuts[cuts.length-1]<xpath.length()-1)
104             return xpath;
105         return "";
106     }
107
108     public static String JavaDoc[] extractTokens(String JavaDoc xpath)
109     {
110         ArrayList JavaDoc arr = new ArrayList JavaDoc();
111         int[] cuts = getElemDelimitersPositions(xpath);
112         int iTokenPos = 0;
113         for(int i=0; i<cuts.length; i++)
114         {
115             if(iTokenPos==cuts[i]) //empty element
116
{
117                 arr.add("");
118             }
119             else
120             {
121                 arr.add(xpath.substring(iTokenPos, cuts[i]));
122             }
123             iTokenPos = cuts[i] +1;
124         }
125         if(iTokenPos<xpath.length()-1)
126         {
127             arr.add(xpath.substring(iTokenPos));
128         }
129         return (String JavaDoc[])arr.toArray(new String JavaDoc[arr.size()]);
130     }
131
132     public static int[] getElemDelimitersPositions(String JavaDoc xpath)
133     {
134          return getElemDelimitersPositions(xpath, -1);
135     }
136
137     public static int[] getElemDelimitersPositions(String JavaDoc xpath, int maxDeep)
138     {
139         int[] arr = new int[100];
140         int length = 0;
141         char[] buf = xpath.toCharArray();
142         int i=0;
143         int iNext;
144         while(maxDeep!=0 && (iNext=getNextElemDelimiterPos(buf, i))>=0)
145         {
146             //add token boundary to list
147
arr[length++] = iNext;
148             maxDeep--;
149             i = iNext+1;
150         }
151         int[] ret_arr = new int[length];
152         for(i=0; i<length; i++)
153             ret_arr[i] = arr[i];
154         return ret_arr;
155     }
156
157     public static boolean isAbsoluteXPath(String JavaDoc xpath)
158     {
159         return (xpath!=null && xpath.startsWith("/"));
160     }
161     
162     private static int getNextElemDelimiterPos(char[] buf, int iFrom)
163     {
164         int i = iFrom;
165         while(i>=0 && i<buf.length)
166         {
167             if(buf[i]=='/')
168                 return i;
169             if(buf[i]=='\'' || buf[i]=='"')
170             {
171                 i = indexOf(buf, i+1, buf[i]); //in suggestion that there is no similar symbols inside
172
if(i>0)
173                    i++;
174                 continue;
175             }
176             i++;
177         }
178         return -1;
179     }
180     
181     private static int indexOf(char[] buf, int iFrom, char chr)
182     {
183         for(int i=iFrom; i<buf.length; i++)
184         {
185             if(buf[i]==chr)
186                 return i;
187         }
188         return -1;
189     }
190     
191     
192     /**
193      * Convert a DTD name into a bean name:
194      *
195      * Any - or _ character is removed. The letter following - and _
196      * is changed to be upper-case.
197      * If the user mixes upper-case and lower-case, the case is not
198      * changed.
199      * If the Word is entirely in upper-case, the word is changed to
200      * lower-case (except the characters following - and _)
201      * The first letter is always upper-case.
202      */

203     public static String JavaDoc convertName(String JavaDoc name) {
204         CharacterIterator JavaDoc ci;
205         StringBuffer JavaDoc n = new StringBuffer JavaDoc();
206         boolean up = true;
207         boolean keepCase = false;
208         char c;
209         
210         // hack need for schema2beans limitation.
211
if(name.equals("property")) {
212             name = "element-property";
213         }
214         
215         ci = new StringCharacterIterator JavaDoc(name);
216         c = ci.first();
217         
218         // If everything is uppercase, we'll lowercase the name.
219
while (c != CharacterIterator.DONE) {
220             if (Character.isLowerCase(c)) {
221                 keepCase = true;
222                 break;
223             }
224             c = ci.next();
225         }
226         
227         c = ci.first();
228         while (c != CharacterIterator.DONE) {
229             if (c == '-' || c == '_')
230                 up = true;
231             else {
232                 if (up)
233                     c = Character.toUpperCase(c);
234                 else
235                     if (!keepCase)
236                         c = Character.toLowerCase(c);
237                 n.append(c);
238                 up = false;
239             }
240             c = ci.next();
241         }
242         return n.toString();
243     }
244     
245     static AttributeList JavaDoc resolve(ConfigContext ctx, ArrayList JavaDoc xpathes, String JavaDoc onlyPrefix)
246     {
247         AttributeList JavaDoc merge_list = null;
248         if(xpathes!=null)
249         {
250             merge_list = new AttributeList JavaDoc();
251             for(int i=0; i<xpathes.size(); i++)
252             {
253                 AttributeList JavaDoc list = resolve(ctx, (String JavaDoc)xpathes.get(i), onlyPrefix);
254                 if(list!=null)
255                     merge_list.addAll(list);
256             }
257         }
258         return merge_list;
259     }
260
261     static AttributeList JavaDoc resolve(ConfigContext ctx, String JavaDoc xpath, String JavaDoc prefixFilter)
262     {
263         if(xpath==null)
264             return null;
265         String JavaDoc[] elems = extractTokens(xpath);
266         if(elems.length==0 || elems[0].length()!=0)
267            return null;
268         ConfigBean cb = null;
269         try {
270             cb = ctx.getRootConfigBean();
271         } catch (ConfigException ce){
272         }
273         AttributeList JavaDoc list = new AttributeList JavaDoc();
274         navigate(cb, elems, 1, prefixFilter, list);
275         return list;
276         
277     }
278     
279     private static void addAttributeToList(String JavaDoc attrName, ConfigBean cb, AttributeList JavaDoc list, String JavaDoc xpath)
280     {
281         String JavaDoc attrValue = getBeanAttributeValue(cb, attrName);
282         if(attrValue!=null)
283         {
284 //System.out.println(" --------->>>addAttributeToList: "+xpath+"/@"+attrName + "=" + attrValue );
285
list.add(new Attribute JavaDoc(xpath+"/@"+attrName, attrValue));
286         }
287     }
288
289     private static ConfigBean getNextBean(ConfigBean cb, String JavaDoc name)
290     {
291         try{
292             if("..".equals(name))
293                return (ConfigBean)cb.parent();
294             return (ConfigBean)cb.getValue(convertName(name));
295         } catch(Throwable JavaDoc t){
296             return null;
297         }
298     }
299
300     private static ConfigBean[] getNextBeans(ConfigBean cb, String JavaDoc name)
301     {
302         try{
303             if("..".equals(name))
304             {
305                ConfigBean parent = (ConfigBean)cb.parent();
306                if(parent==null)
307                    return null;
308                ConfigBean grand = (ConfigBean)parent.parent();
309                if(grand==null)
310                    return new ConfigBean[]{parent};
311                return (ConfigBean[])grand.getValue(parent.name());
312             }
313             return (ConfigBean[])cb.getValues(convertName(name));
314         } catch(Throwable JavaDoc t){
315             return null;
316         }
317     }
318
319     public static String JavaDoc getBeanAttributeValue(ConfigBean cb, String JavaDoc name)
320     {
321         try{
322             return cb.getAttributeValue(convertName(name));
323         } catch(Throwable JavaDoc t){
324             return null;
325         }
326     }
327     
328     private static void navigate(ConfigBean cb, String JavaDoc[] tokens, int iCurrentToken, String JavaDoc prefixFilter, AttributeList JavaDoc list)
329     {
330         if(cb==null || tokens==null || tokens.length<=iCurrentToken)
331             return;
332         String JavaDoc xpath = cb.getXPath();
333         if(xpath==null)
334             return;
335         
336         //stop navigation according to prefix filter
337
if(prefixFilter!=null && prefixFilter.length()>0)
338         {
339             if(xpath.length()>=prefixFilter.length())
340             {
341                 if(!xpath.startsWith(prefixFilter))
342                     return;
343             }
344             else
345             {
346                 if(!prefixFilter.startsWith(xpath))
347                     return;
348             }
349         }
350         
351 //System.out.println( "###>>navigate iCurrentToken=" + iCurrentToken + " cb=" + xpath );
352
//*********************
353
//1. Maybe this is it
354
if(iCurrentToken==tokens.length-1)
355         {
356             list.add(new Attribute JavaDoc(xpath, cb));
357             return;
358         }
359         
360         //goto the next token
361
int iNextToken = iCurrentToken+1;
362         String JavaDoc nextToken = tokens[iNextToken];
363         //*********************
364
//2. Maybe next token is attribute name
365
if(iNextToken==(tokens.length-1) && nextToken.startsWith("@"))
366         {
367 // try {
368
if("@*".equals(nextToken)) //all names
369
{
370                     String JavaDoc[] names = cb.getAttributeNames();
371                     if(names.length>0)
372                         for(int i=0; i<names.length; i++)
373                             addAttributeToList(names[i], cb, list, xpath);
374                 }
375                 else //only one attrname
376
addAttributeToList(nextToken.substring(1), cb, list, xpath);
377 // } catch (ConfigException ce) {
378
// }
379
return;
380         }
381         //*********************************************
382
//3. what if "//"-wildcard or "*" (all children)
383
if(nextToken.length()==0 ||
384            "*".equals(nextToken))
385         {
386             ConfigBean[] children = cb.getAllChildBeans();
387             if(children!=null)
388                 for(int i=0; i<children.length; i++)
389                 {
390                     if(nextToken.length()==0)
391                         navigate(children[i], tokens, iCurrentToken , prefixFilter, list);
392                     
393                     navigate(children[i], tokens, iNextToken , prefixFilter, list);
394                 }
395             return;
396         }
397         
398         //************************************************
399
//4. looks like new element. First, non-indexed
400
if(!nextToken.endsWith("]"))
401         {
402             ConfigBean cbNext = getNextBean(cb, nextToken);
403             if(cbNext!=null)
404                 navigate((ConfigBean)cbNext, tokens, iNextToken , prefixFilter, list);
405             return;
406         }
407         
408         //get index.
409
int indexStartPos = nextToken.indexOf("[");
410         String JavaDoc indexStr = nextToken.substring(indexStartPos+1, nextToken.length()-1);
411         String JavaDoc baseName = nextToken.substring(0, indexStartPos);
412
413         //************************************************
414
//5. [*]?
415
if("*".equals(indexStr)) //all of kind
416
{
417             ConfigBean[] beans = getNextBeans(cb, baseName);
418             if(beans!=null)
419             {
420                 for(int i=0; i<beans.length; i++)
421                 {
422                     navigate(beans[i], tokens, iNextToken , prefixFilter, list);
423                 }
424             }
425             return;
426         }
427         
428         //************************************************
429
//5. [@xxx='yyy']?
430
if(indexStr.startsWith("@") && indexStr.startsWith("'")) //all of kind
431
{
432             String JavaDoc attrName = indexStr.substring(1, indexStr.indexOf('='));
433             String JavaDoc attrValue = indexStr.substring(indexStr.indexOf("='")+2, indexStr.length()-2);
434             ConfigBean[] beans = getNextBeans(cb, baseName);
435             if(beans!=null)
436             {
437                 for(int i=0; i<beans.length; i++)
438                 {
439                     String JavaDoc value = getBeanAttributeValue(beans[i], convertName(attrName));
440                     if(value==null)
441                         continue;
442                     if(attrValue.equals("*") || attrValue.equals(value))
443                         navigate(beans[i], tokens, iNextToken , prefixFilter, list);
444                 }
445             }
446             return;
447         }
448         //6 [number] not yet
449
}
450
451      /**
452       * get
453       */

454 /**
455      public String[] getAttrValueAmongSiblings(ConfigBean cb) {
456          ArrayList cbRet = new ArrayList();
457          ConfigBean parent = (ConfigBean)this.parent();
458          if(parent!=null)
459          {
460              String[] childNames = parent.getChildnt(BeanNames();
461              if(childNames == null || childNames.length == 0)
462                  return null;
463              ConfigBean[] cbs = parent.getChildBeansByName(this.name());
464              if(cbs == null)
465                  cbs=null;
466          }
467          return toConfigBeanArray(cbRet);
468      }
469  **/

470 }
Popular Tags