KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jcorporate > expresso > ext > xml > dbobj > ControllerXSLMap


1 /* ====================================================================
2  * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
3  *
4  * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  *
18  * 3. The end-user documentation included with the redistribution,
19  * if any, must include the following acknowledgment:
20  * "This product includes software developed by Jcorporate Ltd.
21  * (http://www.jcorporate.com/)."
22  * Alternately, this acknowledgment may appear in the software itself,
23  * if and wherever such third-party acknowledgments normally appear.
24  *
25  * 4. "Jcorporate" and product names such as "Expresso" must
26  * not be used to endorse or promote products derived from this
27  * software without prior written permission. For written permission,
28  * please contact info@jcorporate.com.
29  *
30  * 5. Products derived from this software may not be called "Expresso",
31  * or other Jcorporate product names; nor may "Expresso" or other
32  * Jcorporate product names appear in their name, without prior
33  * written permission of Jcorporate Ltd.
34  *
35  * 6. No product derived from this software may compete in the same
36  * market space, i.e. framework, without prior written permission
37  * of Jcorporate Ltd. For written permission, please contact
38  * partners@jcorporate.com.
39  *
40  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
41  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
42  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43  * DISCLAIMED. IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
44  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
45  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
46  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
47  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
49  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
50  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  * ====================================================================
53  *
54  * This software consists of voluntary contributions made by many
55  * individuals on behalf of the Jcorporate Ltd. Contributions back
56  * to the project(s) are encouraged when you make modifications.
57  * Please send them to support@jcorporate.com. For more information
58  * on Jcorporate Ltd. and its products, please see
59  * <http://www.jcorporate.com/>.
60  *
61  * Portions of this software are based upon other open source
62  * products and are subject to their respective licenses.
63  */

64
65 package com.jcorporate.expresso.ext.xml.dbobj;
66
67 import com.jcorporate.expresso.core.db.DBException;
68 import com.jcorporate.expresso.core.dbobj.DBObject;
69 import com.jcorporate.expresso.core.dbobj.SecuredDBObject;
70 import com.jcorporate.expresso.core.dbobj.ValidValue;
71 import com.jcorporate.expresso.core.security.User;
72 import org.apache.commons.collections.LRUMap;
73 import org.apache.oro.text.regex.MalformedPatternException;
74 import org.apache.oro.text.regex.Pattern;
75 import org.apache.oro.text.regex.PatternCompiler;
76 import org.apache.oro.text.regex.PatternMatcher;
77 import org.apache.oro.text.regex.Perl5Compiler;
78 import org.apache.oro.text.regex.Perl5Matcher;
79
80 import java.util.Enumeration JavaDoc;
81 import java.util.Iterator JavaDoc;
82 import java.util.Map JavaDoc;
83 import java.util.Vector JavaDoc;
84
85 //Object cache to hold compiled regular expressions
86

87
88 /**
89  * <p>Entries here define the mapping between a specific user and browser type and
90  * Controller combination to the correct XSL stlyesheet to be used to transform the
91  * outputs of this controller. This allows different users (by group) to see different
92  * representations of a Controller's output, allowing for personalization, and
93  * different browsers to get different XSL transformations as well. As a single
94  * combination of user/browser/controller might match more than one stylesheet
95  * potentially, there is a "sequence" in these combinations. The stylesheet with the
96  * lowest sequence that matches all of the other criteria is selected.</p>
97  *
98  * @author Michael Nash
99  */

100 public class ControllerXSLMap
101         extends SecuredDBObject {
102     private static final String JavaDoc thisClass = ControllerXSLMap.class.getName() + ".";
103
104     /**
105      * Used to hold compiled regular expressions in an attempt to speed
106      * up pattern matching.
107      */

108     protected static Map regExpCache = null;
109
110     /**
111      * Used for regular expression compilation
112      */

113     protected static PatternCompiler compiler = new Perl5Compiler();
114
115     /**
116      * Used to match compiled patterns against strings
117      */

118     protected static PatternMatcher matcher = new Perl5Matcher();
119
120     /**
121      * Constructor
122      */

123     public ControllerXSLMap()
124             throws DBException {
125         super();
126     } /* ControllerXSLMap() */
127
128     /**
129      * Normal DBObject Constructor
130      *
131      * @param uid The user id of the person to have the permissions of this DBOBject
132      */

133     public ControllerXSLMap(int uid)
134             throws DBException {
135         super(uid);
136     } /* ControllerXSLMap(String) */
137
138     /**
139      * Creates the object cache based upon the size of the controllerXSL map.
140      *
141      * @param mapList the ControllerXSLMap dbobject
142      */

143     private synchronized void createObjectCache(ControllerXSLMap mapList) {
144         try {
145             if (regExpCache == null) {
146                 int numMatches = mapList.count();
147
148                 //Let's limit the size of the cache in case it's really
149
//ridiculous
150
if (numMatches > 60) {
151                     numMatches = 60;
152                 }
153
154                 regExpCache = new LRUMap(numMatches);
155             }
156         } catch (DBException dbe) {
157             regExpCache = new LRUMap(60);
158         }
159     }
160
161     /**
162      * Get's the regular expression patter to match against.
163      *
164      * @param controllerClass the classname of the controller to get the appropriate
165      * pattern match
166      * @return a precompiled Regular Expression pattern
167      * @throws DBException if the mattern match is bad.
168      */

169     private synchronized Pattern getPattern(String JavaDoc controllerClass)
170             throws DBException {
171         Pattern p = (Pattern) regExpCache.get(controllerClass);
172
173         if (p == null) {
174             try {
175                 p = compiler.compile(controllerClass, Perl5Compiler.READ_ONLY_MASK);
176                 regExpCache.put(controllerClass, p);
177             } catch (MalformedPatternException mpe) {
178                 throw new DBException(thisClass + "getPattern(String)", mpe);
179             }
180         }
181
182         return p;
183     }
184
185     /**
186      * wlo: This is a copy of getMatch(String, String, String). I changed
187      * the parameter for the UserAgent from 'String userAgentString' to
188      * 'int userAgentId' because this is what actually is passed by the
189      * XMLViewHandler (see changes there).
190      * <p/>
191      * Figure out which XSL map entry should match, given a username, trx class name
192      * and User-Agent string & set this db object to the appropriate object.
193      *
194      * @param userName the username of the currently logged in user.
195      * @param controllerClassParam the Controller classname to match against
196      * @param userAgentId the id of the User Agent as for the User Agent table
197      * @return true if we have found a match.
198      * @throws DBException if there's an error communicating with the underlying table
199      */

200     public synchronized boolean getMatch(String JavaDoc userName,
201                                          String JavaDoc controllerClassParam,
202                                          int userAgentId)
203             throws DBException {
204
205
206         /* wlo: no need to get UserAgent object unless we
207            want to verify the passed userAgentId which
208            is not necessary in my opinion */

209 // UserAgent ua = new UserAgent();
210
// ua.setDBName(getDBName());
211
// ua.setField("UserAgent", userAgentId);
212
// ua.retrieve();
213

214         /* Now get the list of groups that the user is in */
215         User oneUser = new User();
216         oneUser.setDataContext(getDataContext());
217         /* wlo: use special setter method instead of generic setField() method */
218         //oneUser.setField("LoginName", userName);
219
oneUser.setLoginName(userName);
220         /* wlo: retrieve only works with key fields */
221         //oneUser.retrieve();
222
oneUser.find();
223
224         Vector JavaDoc groupList = oneUser.getGroups();
225         ControllerXSLMap oneMap = null;
226         ControllerXSLMap mapList = new ControllerXSLMap();
227         /* wlo: since we get the UserAgent id as parameter, we
228            can use it here */

229         //mapList.setField("UserAgent", ua.getField("UserAgent"));
230
mapList.setField("UserAgent", userAgentId);
231         mapList.setDataContext(getDataContext());
232         createObjectCache(mapList);
233
234         for (Iterator JavaDoc i = mapList.searchAndRetrieveList("MatchSeq").iterator();
235              i.hasNext();) {
236             oneMap = (ControllerXSLMap) i.next();
237
238             String JavaDoc oneGroup = null;
239
240             for (Enumeration JavaDoc eg = groupList.elements(); eg.hasMoreElements();) {
241                 oneGroup = (String JavaDoc) eg.nextElement();
242
243                 if (oneGroup.equals(oneMap.getField("GroupName"))) {
244                     String JavaDoc controllerClass = oneMap.getField("ControllerClass");
245                     Pattern compiledRegExp = getPattern(controllerClass);
246
247                     boolean result;
248                     synchronized (matcher) {
249                         result = matcher.matches(controllerClassParam,
250                                 compiledRegExp);
251
252                     }
253                     if (result) {
254                         /* wlo: oneMap.getField("MapNumber") to oneMap.getField("MatchNumber")
255                          This is only a guess since I did not spent much thougts on
256                      the idea behind MatchSeq, MatchNumber and so on. */

257                         setField("MatchNumber",
258                                 oneMap.getField("MatchNumber"));
259                         retrieve();
260
261                         return true;
262                     }
263                     /* if we match the transaction expression */
264
265                 } /* if we match the group expression */
266
267             } /* for each group the user belongs to */
268
269         }
270
271         return false;
272     } /* getMatch(String, String, String) */
273
274
275     /**
276      * Figure out which XSL map entry should match, given a username, trx class name
277      * and User-Agent string & set this db object to the appropriate object.
278      *
279      * @param userName the name of the user logged in
280      * @param controllerClassName the classname of the controller to check against.
281      * @param userAgentString the useragent string to check against.
282      * @return true if we have found a match
283      * @throws DBException if there's an error communicating with the underlying
284      * database
285      */

286     public synchronized boolean getMatch(String JavaDoc userName, String JavaDoc controllerClassName,
287                                          String JavaDoc userAgentString)
288             throws DBException {
289         /* Determine which UserAgent identifier/code we match */
290         UserAgent ua = new UserAgent();
291         ua.setDataContext(getDataContext());
292         ua.getMatch(userAgentString);
293
294         /* Now get the list of groups that the user is in */
295         User oneUser = new User();
296         oneUser.setDataContext(getDataContext());
297         oneUser.setLoginName(userName);
298         //oneUser.setField("UserName", userName);
299
if (!oneUser.find()) {
300             throw new DBException("User not found: '" + userName + "'");
301         }
302
303         Vector JavaDoc groupList = oneUser.getGroups();
304         ControllerXSLMap oneMap = null;
305         ControllerXSLMap mapList = new ControllerXSLMap();
306         mapList.setField("UserAgent", ua.getField("UserAgent"));
307         mapList.setDataContext(getDataContext());
308         createObjectCache(mapList);
309
310         for (Iterator JavaDoc i = mapList.searchAndRetrieveList("MatchSeq").iterator();
311              i.hasNext();) {
312             oneMap = (ControllerXSLMap) i.next();
313
314             String JavaDoc oneGroup = null;
315
316             for (Enumeration JavaDoc eg = groupList.elements(); eg.hasMoreElements();) {
317                 oneGroup = (String JavaDoc) eg.nextElement();
318
319                 if (oneGroup.equals(oneMap.getField("GroupName"))) {
320                     String JavaDoc controllerClass = oneMap.getField("ControllerClass");
321                     Pattern compiledRegExp = getPattern(controllerClass);
322
323                     boolean result;
324                     synchronized (matcher) {
325                         result = matcher.matches(controllerClassName, compiledRegExp);
326                     }
327                     if (result) {
328                         setField("MatchNumber", oneMap.getField("MapNumber"));
329                         retrieve();
330
331                         return true;
332                     } /* if we match the transaction expression */
333
334                 } /* if we match the group expression */
335
336             } /* for each group the user belongs to */
337
338         }
339
340         return false;
341     } /* getMatch(String, String, String) */
342
343
344     /**
345      * Standard method to return a new CacheSync object
346      *
347      * @return DBObject A new CacheSync object
348      * @throws DBException If the new object cannot be created
349      */

350     public DBObject getThisDBObj()
351             throws DBException {
352         return (DBObject) new ControllerXSLMap();
353     } /* getThisDBObj() */
354
355
356     /**
357      * Override the method getValues to provide specific values for our
358      * multi-valued fields
359      *
360      * @param fieldName Fielname to retrieve values for
361      * @return Vector of ValidValue Value/description pairs for this field
362      * @throws DBException If the values cannot be retrieved
363      */

364     public synchronized Vector JavaDoc getValidValues(String JavaDoc fieldName)
365             throws DBException {
366         if (fieldName.equals("Protocol")) {
367             Vector JavaDoc myValues = new Vector JavaDoc(4);
368             myValues.addElement(new ValidValue("http", "HTTP"));
369             myValues.addElement(new ValidValue("jobqueue", "Via Job Queue"));
370
371             return myValues;
372         }
373
374         return super.getValidValues(fieldName);
375     } /* getValidValues(String) */
376
377
378     /**
379      * Define the table and fields for this object
380      *
381      * @throws DBException If the fields cannot be set up
382      */

383     public void setupFields()
384             throws DBException {
385         setTargetTable("CTLXSLMAP");
386         setDescription("Controller/XSL Mapping Entries");
387         setCharset("ISO-8859-1");
388         addField("MatchNumber", "int", 0, false, "Match Number");
389         addField("ControllerClass", "text", 0, false,
390                 "Controller Class Pattern");
391         addField("MatchSeq", "int", 0, false, "Match Sequence");
392         addField("GroupName", "varchar", 10, false, "User Group");
393         addField("XSLFileName", "text", 0, false, "XSL File Name");
394         addField("UserAgent", "int", 0, false, "User-Agent/Browser");
395         addField("Param", "text", 0, false, "Additional Parameters");
396         addKey("MatchNumber");
397     } /* setupFields() */
398
399
400 } /* ControllerXSLMap */
401
402 /* ControllerXSLMap */
Popular Tags