KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > module > builders > Jumpers


1 /*
2
3  This software is OSI Certified Open Source Software.
4  OSI Certified is a certification mark of the Open Source Initiative.
5
6  The license (Mozilla version 1.0) can be read at the MMBase site.
7  See http://www.MMBase.org/license
8
9  */

10 package org.mmbase.module.builders;
11
12 import java.util.*;
13
14 import javax.servlet.http.HttpServletResponse JavaDoc;
15 import javax.servlet.http.HttpServletRequest JavaDoc;
16
17 import org.mmbase.bridge.Field;
18 import org.mmbase.cache.Cache;
19 import org.mmbase.core.CoreField;
20 import org.mmbase.core.event.NodeEvent;
21 import org.mmbase.module.core.*;
22 import org.mmbase.storage.search.implementation.*;
23 import org.mmbase.storage.search.*;
24 import org.mmbase.util.logging.*;
25 import org.mmbase.util.functions.*;
26
27 /**
28  * Maintains jumpers for redirecting urls. The data stored in this builder is
29  * used to redirect urls based ons a specific key. The jumpers builder is called
30  * from the {@link org.mmbase.servlet.JumpersFilter}. <br />
31  * The jumpers builder can be configured using two properties: <br />
32  * <ul>
33  * <li><code>JumperCacheSize</code> determines the size of the jumper cache
34  * (in nr of items). The default size is 1000.</li>
35  * <li><code>JumperNotFoundURL</code> Determines the default url (such as a
36  * home page or error page) when no jumper is found. If not specified nothing
37  * will be done if no jumper is found.</li>
38  * </ul>
39  * <br />
40  * XXX:Note that this builder is called directly from a servlet, and may
41  * therefor be bound to the cloud context rather than a cloud. This would mean
42  * that in a multi-cloud environment, this builder will be shared.
43  *
44  * @application Tools, Jumpers
45  * @author Daniel Ockeloen
46  * @author Pierre van Rooden (javadocs)
47  * @version $Id: Jumpers.java,v 1.36 2006/07/05 15:15:07 pierre Exp $
48  */

49 public class Jumpers extends MMObjectBuilder {
50
51     /**
52      * Default Jump Cache Size. Customization can be done through the central
53      * caches.xml Make an entry under the name "JumpersCache" with the size you
54      * want.
55      */

56     private static final int DEFAULT_JUMP_CACHE_SIZE = 1000;
57
58     private static final Logger log = Logging.getLoggerInstance(Jumpers.class);
59
60     /**
61      * Cache for URL jumpers.
62      */

63     protected JumpersCache jumpCache = new JumpersCache(DEFAULT_JUMP_CACHE_SIZE);
64
65     /**
66      * Default redirect if no jumper can be found. If this field is
67      * <code>null</code>, a url will not be 'redirected' if the search for a
68      * jumper failed. This may cause a 404 error on your server if the path
69      * specified is unavailable. However, you may need it if other servlets rely
70      * on specific paths that would otherwise be caught by the jumper servlet.
71      * The value fo this field is set using the <code>JumperNotFoundURL</code>
72      * property in the builder configuration file.
73      */

74     protected static String JavaDoc jumperNotFoundURL;
75
76     /**
77      * Initializes the builder. Determines the jumper cache size, and
78      * initializes it. Also determines the default jumper url.
79      *
80      * @return always <code>true</code>
81      */

82     public boolean init() {
83         super.init();
84         jumperNotFoundURL = getInitParameter("JumperNotFoundURL");
85         return true;
86     }
87
88     /**
89      * @since MMBase-1.7.1
90      */

91     protected String JavaDoc getGUIIndicator(MMObjectNode node, Parameters args) {
92         String JavaDoc field = (String JavaDoc) args.get("field");
93         if (field == null || field.equals("url")) {
94             String JavaDoc url = node.getStringValue("url");
95             HttpServletRequest JavaDoc req = (HttpServletRequest JavaDoc) args.get(Parameter.REQUEST);
96             HttpServletResponse JavaDoc res = (HttpServletResponse JavaDoc) args.get(Parameter.RESPONSE);
97             String JavaDoc link;
98             if (url.startsWith("http:") || url.startsWith("https:") || url.startsWith("ftp:")) {
99                 link = url;
100             } else if (!url.startsWith("/")) { // requested relative to context
101
// path
102
String JavaDoc context = req == null ? MMBaseContext.getHtmlRootUrlPath() : req.getContextPath();
103                 String JavaDoc u = context + "/" + url;
104                 link = res == null ? u : res.encodeURL(u);
105             } else {
106                 String JavaDoc context = req == null ? MMBaseContext.getHtmlRootUrlPath() : req.getContextPath();
107                 // request relative to host's root
108
if (url.startsWith(context + "/")) { // in this context!
109
String JavaDoc u = url.substring(context.length() + 1);
110                     link = res == null ? u : res.encodeURL(u);
111                 } else { // in other context
112
link = url;
113                 }
114             }
115             return "<a HREF=\"" + link + "\" target=\"extern\">" + url + "</a>";
116         } else {
117             if (field == null || field.equals("")) {
118                 return super.getGUIIndicator(node);
119             } else {
120                 return super.getGUIIndicator(field, node);
121             }
122         }
123
124     }
125
126     /**
127      * Retrieves a jumper for a specified key.
128      *
129      * @param tok teh tokenizer, in which the first token is the key to search
130      * for.
131      * @return the found alternate url.
132      */

133     public String JavaDoc getJump(StringTokenizer tok) {
134         String JavaDoc key = tok.nextToken();
135         return getJump(key);
136     }
137
138     /**
139      * Removes a specified key from the cache.
140      *
141      * @param key the key to remove
142      */

143     public void delJumpCache(String JavaDoc key) {
144         if (key != null) {
145             log.debug("Jumper builder - Removing " + key + " from jumper cache");
146             jumpCache.remove(key);
147         }
148     }
149
150     // jump on content of 'name' or 'id' field
151
private String JavaDoc getJumpByField(String JavaDoc fieldName, String JavaDoc key) {
152         NodeSearchQuery query = new NodeSearchQuery(this);
153         CoreField field = getField(fieldName); // "name");
154
StepField queryField = query.getField(field);
155         StepField numberField = query.getField(getField(FIELD_NUMBER));
156         BasicSortOrder sortOrder = query.addSortOrder(numberField); // use 'oldest' jumper
157
BasicFieldValueConstraint cons = null;
158         if (field.getType() == Field.TYPE_STRING) {
159             cons = new BasicFieldValueConstraint(queryField, key);
160         } else if (field.getType() == Field.TYPE_INTEGER) {
161             try {
162                 cons = new BasicFieldValueConstraint(queryField, new Integer JavaDoc(key));
163             } catch(NumberFormatException JavaDoc e) { log.error("this key("+key+") should be a number because field("+fieldName+") is of type int!");
164                 cons = null;
165             }
166         }
167         query.setConstraint(cons);
168         query.setMaxNumber(1);
169         try {
170             List resultList = getNodes(query);
171             if (resultList.size() > 0) {
172                 MMObjectNode node = (MMObjectNode) resultList.get(0);
173                 return node.getStringValue("url");
174             }
175         } catch (SearchQueryException sqe) {
176             log.error(sqe.getMessage());
177         }
178         return null;
179     }
180
181     /**
182      * Retrieves a jumper for a specified key.
183      *
184      * @param key the key to search for.
185      * @return the found alternate url.
186      */

187     public String JavaDoc getJump(String JavaDoc key) {
188         String JavaDoc url = null;
189
190         if (key.equals("")) {
191             url = jumperNotFoundURL;
192         } else {
193             url = (String JavaDoc) jumpCache.get(key);
194             if (log.isDebugEnabled()) {
195                 if (url != null) {
196                     log.debug("Jumper - Cache hit on " + key);
197                 } else {
198                     log.debug("Jumper - Cache miss on " + key);
199                 }
200             }
201             if (url == null) {
202                 // Search jumpers with name;
203
url = getJumpByField("name", key);
204             }
205             int ikey = -1;
206             if (url == null) {
207                 try {
208                     ikey = Integer.parseInt(key);
209                 } catch (NumberFormatException JavaDoc e) {}
210                 // Search jumpers with number (parent);
211
if (ikey >= 0) {
212                     url = getJumpByField("id", key);
213                 }
214             }
215             if (url == null) {
216                 // no direct url call its builder
217
if (ikey >= 0) {
218                     MMObjectNode node = getNode(ikey);
219                     if (node != null) {
220                         String JavaDoc buln = mmb.getTypeDef().getValue(node.getIntValue("otype"));
221                         MMObjectBuilder bul = mmb.getMMObject(buln);
222                         if (log.isDebugEnabled()) {
223                             log.debug("getUrl through builder with name=" + buln + " and id " + ikey);
224                         }
225                         if (bul != null) {
226                             url = bul.getDefaultUrl(ikey);
227                         }
228                     }
229                 }
230             }
231             if (url != null && url.length() > 0 && !url.equals("null")) {
232                 jumpCache.put(key, url);
233                 if (url.equalsIgnoreCase("NOREDIRECT")) { // return null if the
234
// url specified is
235
// NOREDIRECT
236
url = null;
237                 }
238             } else {
239                 if (log.isDebugEnabled()) {
240                     log.debug("No jumper found for key '" + key + "'");
241                 }
242                 url = jumperNotFoundURL;
243             }
244         }
245         return url;
246     }
247
248     /*
249      * (non-Javadoc)
250      *
251      * @see org.mmbase.module.core.MMObjectBuilder#notify(org.mmbase.core.event.NodeEvent)
252      */

253     public void notify(NodeEvent event) {
254         log.debug("Jumpers=" + event.getMachine() + " " + event.getBuilderName() + " no="
255             + event.getNodeNumber()+ " " + NodeEvent.newTypeToOldType(event.getType()));
256         jumpCache.clear();
257         super.notify(event);
258     }
259
260     protected Object JavaDoc executeFunction(MMObjectNode node, String JavaDoc function, List arguments) {
261         if (function.equals("gui")) {
262             String JavaDoc rtn;
263             if (arguments == null || arguments.size() == 0) {
264                 rtn = getGUIIndicator(node);
265             } else {
266                 rtn = getGUIIndicator(node, Functions.buildParameters(GUI_PARAMETERS, arguments));
267             }
268             if (rtn != null) return rtn;
269         }
270         return super.executeFunction(node, function, arguments);
271     }
272
273 }
274
275 class JumpersCache extends Cache {
276     public String JavaDoc getName() {
277         return "JumpersCache";
278     }
279
280     public String JavaDoc getDescription() {
281         return "Cache for Jumpers";
282     }
283
284     JumpersCache(int size) {
285         super(size);
286         putCache(this);
287     }
288 }
289
Popular Tags