View Javadoc

1   package net.kwfgrid.gwui.servlets;
2   
3   import java.util.*;
4   
5   /***
6    * Created by IntelliJ IDEA.
7    * User: Ondrej
8    * Date: 11.8.2006
9    * Time: 9:19:59
10   * To change this template use File | Settings | File Templates.
11   */
12  public class XmlTag
13  {    
14      private String name;
15      private String value;
16      private Set subTags;
17      private Map params;
18      private Map nameSpaces;
19  
20      private int strstr( String where, String what )
21      {
22          int retv = -1;
23          int ind;
24          for( int i = 0; i < what.length(); i ++ )
25          {
26              ind = where.indexOf( what.charAt( i ) );
27              if( ( ( retv < 0 ) || ( retv > ind ) ) && ( ind >= 0 ) )
28                  retv = ind;
29          }
30  
31          return retv;
32      }
33  
34      public XmlTag( Map nameSpaces )
35      {
36          subTags = new HashSet();
37          this.nameSpaces = nameSpaces;
38          name = "";
39          value = "";
40          params = new HashMap();
41      }
42  
43      public void setValue( String value )
44      {
45          this.value = value;
46      }
47  
48      public void setName( String name )
49      {
50          this.name = name;
51      }
52  
53      public void addParam( String name, String value )
54      {
55          params.put( name, value );
56      }
57  
58      public String getName()
59      {
60          return name;
61      }
62  
63      public String getValue()
64      {
65          return value;
66      }
67  
68      public Map getParams()
69      {
70          return params;
71      }
72  
73      private String extractFirstTagName( String treeString )
74      {
75          int start = treeString.charAt( 0 ) == '.' ? 1 : 0;
76          int end = strstr( treeString.substring( 1 ), "._" ) + 1;
77          if( end < 1)
78              return treeString.substring( start );
79          else
80              return treeString.substring( start, end );
81      }
82  
83      private String getTreeStringTail( String treeString )
84      {
85          int headEnd = strstr( treeString.substring( 1 ), "._" );
86          if( headEnd < 0 )
87              return "";
88          else
89              return treeString.substring( headEnd + 1 );
90      }
91  
92  
93      /***
94       * Constructs a XmlTag subtree based on the structure of the string (see below).
95       * @param treeString a string in the prescribed form .tag.tag.tag.....tag or .tag.tag.tag...tag_param
96       *                   If treeString begins with tag, the XmlTag will
97       *                   <ul>
98       *                   <li> take it as its name, if it has not any name now
99       *                   <li> remove it and create a subtree based on the rest of the string, if it is the same
100      *                        as its name, if it has a name
101      *                   <li> create a different subtree, if it has a name and the starting tag name in treeString
102      *                        differs from it
103      *                   <li> add parameter for itself, it treeString begins with _
104      *                   </ul>
105      * @param value the value of either the final tag, or of the parameter (depends on whether <b>treeString</b>
106      *              ends with <i>.tag</i> or <i>_param</i>)
107      * @return new XmlTag, which is a peer (has the same parent tag) as this XmlTag, or null, if treeString was
108      *         consumed in the subtree of this XmlTag.
109      */
110     public XmlTag createFromString( String treeString, String value )
111     {
112         if( treeString.length() < 1 )
113             return null;
114 
115         switch( treeString.charAt( 0 ) )
116         {
117             case '.':
118                 String newName = extractFirstTagName( treeString );
119                 String newTail = getTreeStringTail( treeString );
120 
121                 if( newName.length() < 1 )
122                     return null;
123 
124                 if( getName().length() < 1 )
125                 {
126                     setName( newName );
127                     if( ( newTail.length() ) > 0 && ( newTail.charAt( 0 ) == '_' ) )
128                         return createFromString( newTail, value );
129                 }
130 
131                 if( newName.equals( getName() ) )
132                 {
133                     if( newTail.length() > 0 )
134                     {
135                         if( newTail.startsWith( "_" ) )
136                         {
137                             createFromString( newTail, value );
138                             return null;
139                         }
140                         String newNewHead = extractFirstTagName( newTail );
141                         Iterator iter = subTags.iterator();
142                         XmlTag tag;
143                         while( iter.hasNext() )
144                         {
145                             tag = (XmlTag)(iter.next());
146                             if( tag.getName().equals( newNewHead) )
147                             {
148                                 tag.createFromString( newTail, value );
149                                 return null;
150                             }
151                         }
152                         XmlTag newSubTag = new XmlTag( nameSpaces );
153                         subTags.add( newSubTag );
154                         newSubTag.createFromString( newTail, value );
155                     }
156                     else
157                         setValue( value );
158                     return null;
159                 }
160                 else
161                 {
162                     XmlTag newPeerTag = new XmlTag( nameSpaces );
163                     newPeerTag.createFromString( treeString, value );
164                     return newPeerTag;
165                 }
166 
167             case '_':
168                 addParam( treeString.substring( 1 ), value  );
169                 return null;
170         }
171 
172         return null;
173     }
174 
175     public String createStringRepresentation( int indent, boolean includeNameSpaces )
176     {
177         StringBuffer retv = new StringBuffer();
178         //first line - indented name
179         for( int i = 0; i < indent; i ++ )
180             retv.append( '\t' );
181         retv.append( "<" );
182         retv.append( getName() );
183         //add namespaces
184         if( includeNameSpaces && ( nameSpaces.size() > 0 ) )
185         {
186             Iterator iter = nameSpaces.entrySet().iterator();
187             Map.Entry entry;
188             while( iter.hasNext() )
189             {
190                 entry = (Map.Entry)(iter.next());
191                 retv.append( " xmlns" );
192                 if( ((String)(entry.getValue())).length() > 0 )
193                     retv.append(":" ).append( entry.getKey() ).append( "=\"" ).append( entry.getValue() ).append( "\"" );
194                 else
195                     retv.append("=\"\"" );
196             }
197         }
198         //add parameters
199         Iterator iter = params.entrySet().iterator();
200         Map.Entry entry;
201         while( iter.hasNext() )
202         {
203             entry = (Map.Entry)(iter.next());
204             retv.append( " " ).append( entry.getKey() ).append( "=\"" ).append( entry.getValue() ).append( "\"" );
205         }
206         //intermezzo - if we have no value and no subtags, we finish with the /> shortcut right now
207         if( ( getValue().length() < 1 ) && ( subTags.size() < 1 ) )
208         {
209             retv.append( "/>\n");
210             return retv.toString();
211         }
212         retv.append( ">\n" );
213         //second line - indented value
214         if( getValue().length() > 0 )
215         {
216             for( int i = 0; i < indent + 1; i ++ )
217                 retv.append( '\t' );
218             retv.append( getValue() ).append( "\n" );
219         }
220         //third to x-th line - subtags
221         XmlTag subTag;
222         iter = subTags.iterator();
223         while( iter.hasNext() )
224         {
225             subTag = (XmlTag)iter.next();
226             retv.append( subTag.createStringRepresentation( indent + 1, false ) );
227         }
228         //last line - indented token closing
229         for( int i = 0; i < indent; i ++ )
230             retv.append( '\t' );
231         retv.append( "</" );
232         retv.append( getName() );
233         retv.append( ">\n" );
234 
235         return retv.toString();
236     }
237 }