##### Coverage Report - org.webmacro.directive.DirectiveBuilder

Classes in this File | Line Coverage | Branch Coverage | Complexity
DirectiveBuilder |
56% | 34/60
40% | 16/40
| 3.2142857142857144;3.214

1 |  |
     /*
2 |  |
      * Copyright (C) 1998-2000 Semiotek Inc.  All Rights Reserved.
3 |  |
      *
4 |  |
      * Redistribution and use in source and binary forms, with or without
5 |  |
      * modification, are permitted under the terms of either of the following
6 |  |
      * Open Source licenses:
7 |  |
      *
8 |  |
      * The GNU General Public License, version 2, or any later version, as
9 |  |
      * published by the Free Software Foundation
10 |  |
      * (http://www.fsf.org/copyleft/gpl.html);
11 |  |
      *
12 |  |
      *  or
13 |  |
      *
14 |  |
      * The Semiotek Public License (http://webmacro.org/LICENSE.)
15 |  |
      *
16 |  |
      * This software is provided "as is", with NO WARRANTY, not even the
17 |  |
      * implied warranties of fitness to purpose, or merchantability. You
18 |  |
      * assume all risks and liabilities associated with its use.
19 |  |
      *
20 |  |
      * See www.webmacro.org for more information on the WebMacro project.
21 |  |
      */
22 |  |
23 |  |
     package org.webmacro.directive;
24 |  |
25 |  |
     import org.webmacro.engine.BuildContext;
26 |  |
     import org.webmacro.engine.BuildException;
27 |  |
     import org.webmacro.engine.Builder;
28 |  |
29 |  |
     import java.util.Vector;
30 |  |
31 |  |
     /**
32 |  |
      * DirectiveBuilder manages the building of directives.  It is created
33 |  |
      * by the parser, which populates it with the directive arguments, and
34 |  |
      * the DirectiveBuilder.build() method calls the build() method for the
35 |  |
      * appropriate directive.
36 |  |
      * @author Brian Goetz
37 |  |
      */
38 |  |
39 |  |
     public final class DirectiveBuilder implements Builder, DirectiveArgs
40 |  |
     {
41 |  |
42 |  |
         // The descriptor for the directive we're building
43 |  |
         private final DirectiveDescriptor desc;
44 |  |
45 |  |
         // The directive arguments
46 |  |
         private ArgsHolder buildArgs;
47 |  |
48 |  |
         // This is an array of either ArgsHolders (for nonrepeating subdirectives)
49 |  |
         // or Vectors of ArgsHolders (for repeating subdirectives)
50 |  |
         private Object[] subdirectives;
51 |  |
52 | 2 |
         private static final ArgsHolder[] aha = new ArgsHolder[0];
53 |  |
         private static final String
54 |  |
                 EXC_GETSUBD_NOTREPEATING = "getSubdirective: attempt to get repeating "
55 |  |
                 + "subdirective -- use getRepeatingSubdirective() instead",
56 |  |
         EXC_GETSUBD_REPEATING = "getRepeatingSubdirective: attempt to get "
57 |  |
                 + "nonrepeating subdirective -- use getSubdirective() instead";
58 |  |
59 |  |
         public DirectiveBuilder (DirectiveDescriptor desc)
60 | 1288 |
         {
61 | 1288 |
             this.desc = desc;
62 | 1288 |
             if (desc.args != null
63 |  |
                     && desc.args.length > 0)
64 | 1288 |
                 buildArgs = new ArgsHolder(desc.args);
65 | 1288 |
             if (desc.subdirectives != null
66 |  |
                     && desc.subdirectives.length > 0)
67 | 782 |
                 subdirectives = new Object[desc.subdirectives.length];
68 | 1288 |
         }
69 |  |
70 |  |
         private int findSubdirectiveIndex (int id)
71 |  |
                 throws BuildException
72 |  |
         {
73 | 3690 |
             for (int i = 0; i < desc.subdirectives.length; i++)
74 |  |
             {
75 | 3690 |
                 if (desc.subdirectives[i].id == id)
76 | 2236 |
                     return i;
77 |  |
             }
78 | 0 |
             throw new BuildException("Invalid argument ID " + id
79 |  |
                     + " requested for directive " + desc.name);
80 |  |
         }
81 |  |
82 |  |
         public Object getExactArg (int idx) throws BuildException
83 |  |
         {
84 | 0 |
             if (buildArgs == null)
85 | 0 |
                 return null;
86 |  |
             else
87 | 0 |
                 return buildArgs.getExactArg(idx);
88 |  |
         }
89 |  |
90 |  |
         /**
91 |  |
          * How many arguments does this builder have?
92 |  |
          */
93 |  |
         public int getArgCount ()
94 |  |
         {
95 | 0 |
             if (buildArgs == null)
96 | 0 |
                 return 0;
97 |  |
             else
98 | 0 |
                 return buildArgs.getArgCount();
99 |  |
         }
100 |  |
101 |  |
         /**
102 |  |
          * Retrieve the argument whose id is the specified id.
103 |  |
          */
104 |  |
         public Object getArg (int argId)
105 |  |
                 throws BuildException
106 |  |
         {
107 | 0 |
             if (buildArgs == null)
108 | 0 |
                 return null;
109 |  |
             else
110 | 0 |
                 return buildArgs.getArg(argId);
111 |  |
         }
112 |  |
113 |  |
         /**
114 |  |
          * Retrieve the argument whose id is the specified id, and if it is a
115 |  |
          * Builder, build it with the specified build context.
116 |  |
          */
117 |  |
         public Object getArg (int argId, BuildContext bc)
118 |  |
                 throws BuildException
119 |  |
         {
120 | 3136 |
             if (buildArgs == null)
121 | 0 |
                 return null;  // FIXME Should throw exception here, as non-null branch does
122 |  |
             else
123 | 3136 |
                 return buildArgs.getArg(argId, bc);
124 |  |
         }
125 |  |
126 |  |
         /**
127 |  |
          * Find out how many subdirectives of the specified id were present.
128 |  |
          */
129 |  |
         public int getSubdirectiveCount (int subdId)
130 |  |
                 throws BuildException
131 |  |
         {
132 | 0 |
             int i = findSubdirectiveIndex(subdId);
133 | 0 |
             if (subdirectives[i] == null)
134 | 0 |
                 return 0;
135 |  |
             else
136 | 0 |
                 return (desc.subdirectives[i].repeating)
137 |  |
                         ? ((ArgsHolder[]) (subdirectives[i])).length
138 |  |
                         : 1;
139 |  |
         }
140 |  |
141 |  |
         /**
142 |  |
          * Set the argument whose id is the specified id.  If the argument has
143 |  |
          * already been set, it is overwritten.  Generally not used by directives,
144 |  |
          * only used by the parser.
145 |  |
          */
146 |  |
         public void setArg (int argId, Object arg)
147 |  |
                 throws BuildException
148 |  |
         {
149 | 3216 |
             buildArgs.setArg(argId, arg);
150 | 3216 |
         }
151 |  |
152 |  |
         /**
153 |  |
          * Create a new subdirective of the specified id and create an ArgsHolder
154 |  |
          * for its arguments.  Not used by directives.
155 |  |
          */
156 |  |
         public DirectiveArgs newSubdirective (int subdId)
157 |  |
                 throws BuildException
158 |  |
         {
159 | 336 |
             ArgsHolder ah = null;
160 | 336 |
             int index = findSubdirectiveIndex(subdId);
161 | 336 |
             if (!desc.subdirectives[index].repeating)
162 |  |
             {
163 | 336 |
                 if (subdirectives[index] == null)
164 | 336 |
                     subdirectives[index] = new ArgsHolder(desc.subdirectives[index].args);
165 | 336 |
                 ah = (ArgsHolder) subdirectives[index];
166 |  |
             }
167 |  |
             else
168 |  |
             {
169 |  |
                 Vector v;
170 | 0 |
                 if (subdirectives[index] == null)
171 | 0 |
                     subdirectives[index] = new Vector();
172 | 0 |
                 v = (Vector) subdirectives[index];
173 | 0 |
                 ah = new ArgsHolder(desc.subdirectives[index].args);
174 | 0 |
                 v.addElement(ah);
175 |  |
             }
176 |  |
177 | 336 |
             return ah;
178 |  |
         }
179 |  |
180 |  |
         /**
181 |  |
          * Check to see if the specified subdirective is OK at this point.
182 |  |
          * The only reason it wouldn't be is because we've already got one
183 |  |
          * and its not a repeating subdirective
184 |  |
          */
185 |  |
         public boolean subdirectiveOk (int subdId) throws BuildException
186 |  |
         {
187 | 336 |
             int index = findSubdirectiveIndex(subdId);
188 | 336 |
             return desc.subdirectives[index].repeating || subdirectives[index] == null;
189 |  |
         }
190 |  |
191 |  |
         /**
192 |  |
          * Retrieves the ArgsHolder for the associated subdirective so that the
193 |  |
          * subdirective arguments can be retrieved.  Only valid if the specified
194 |  |
          * subdirective is not repeating.
195 |  |
          */
196 |  |
         public ArgsHolder getSubdirective (int subdId)
197 |  |
                 throws BuildException
198 |  |
         {
199 | 782 |
             int index = findSubdirectiveIndex(subdId);
200 | 782 |
             if (desc.subdirectives[index].repeating)
201 | 0 |
                 throw new BuildException(EXC_GETSUBD_NOTREPEATING);
202 | 782 |
             return (ArgsHolder) subdirectives[index];
203 |  |
         }
204 |  |
205 |  |
         /**
206 |  |
          * Retrieves an array of ArgsHolders for the associated subdirective
207 |  |
          * so that the subdirective arguments can be retrieved.  Only valid
208 |  |
          * if the specified subdirective is repeating.
209 |  |
          */
210 |  |
         public ArgsHolder[] getRepeatingSubdirective (int subdId)
211 |  |
                 throws BuildException
212 |  |
         {
213 | 782 |
             int index = findSubdirectiveIndex(subdId);
214 | 782 |
             if (!desc.subdirectives[index].repeating)
215 | 0 |
                 throw new BuildException(EXC_GETSUBD_REPEATING);
216 | 782 |
             if (subdirectives[index] == null)
217 | 782 |
                 return null;
218 |  |
             else
219 | 0 |
                 return (ArgsHolder[]) ((Vector) subdirectives[index]).toArray(aha);
220 |  |
         }
221 |  |
222 |  |
         /**
223 |  |
          * Build the directive.  Calls the build() method of the directive.
224 |  |
          */
225 |  |
         public Object build (BuildContext bc) throws BuildException
226 |  |
         {
227 |  |
             Directive d;
228 |  |
             try
229 |  |
             {
230 | 1284 |
                 d = (Directive) desc.dirClass.newInstance();
231 |  |
             }
232 | 0 |
             catch (Exception e)
233 |  |
             {
234 | 0 |
                 throw new BuildException("Error instantiating Directive object for #"
235 |  |
                         + desc.name);
236 | 1284 |
             }
237 |  |
             ;
238 | 1284 |
             return d.build(this, bc);
239 |  |
         }
240 |  |
241 |  |
         /**
242 |  |
          * Get the name this directive was registered as
243 |  |
          */
244 |  |
         public String getName ()
245 |  |
         {
246 | 0 |
             return desc.name;
247 |  |
         }
248 |  |
     }
249 |  |
250 |  |
251 |  |