001: /*
002: * Helma License Notice
003: *
004: * The contents of this file are subject to the Helma License
005: * Version 2.0 (the "License"). You may not use this file except in
006: * compliance with the License. A copy of the License is available at
007: * http://adele.helma.org/download/helma/license.txt
008: *
009: * Copyright 1998-2003 Helma Software. All Rights Reserved.
010: *
011: * $RCSfile$
012: * $Author: root $
013: * $Revision: 8604 $
014: * $Date: 2007-09-28 15:16:38 +0200 (Fre, 28 Sep 2007) $
015: */
016:
017: package helma.framework.core;
018:
019: import java.util.*;
020: import java.io.UnsupportedEncodingException;
021:
022: import helma.util.UrlEncoded;
023:
024: /**
025: * Represents a URI request path that has been resolved to an object path.
026: * Offers methods to access objects in the path by index and prototype names,
027: * and to render the path as URI again.
028: */
029: public class RequestPath {
030:
031: Application app;
032:
033: List objects;
034: List ids;
035:
036: Map primaryProtos;
037: Map secondaryProtos;
038:
039: /**
040: * Creates a new RequestPath object.
041: *
042: * @param app the application we're running in
043: */
044: public RequestPath(Application app) {
045: this .app = app;
046: objects = new ArrayList();
047: ids = new ArrayList();
048: primaryProtos = new HashMap();
049: secondaryProtos = new HashMap();
050: }
051:
052: /**
053: * Adds an item to the end of the path.
054: *
055: * @param id the item id representing the path in the URL
056: * @param obj the object to which the id resolves
057: */
058: public void add(String id, Object obj) {
059: ids.add(id);
060: objects.add(obj);
061:
062: Prototype proto = app.getPrototype(obj);
063:
064: if (proto != null) {
065: primaryProtos.put(proto.getName(), obj);
066: primaryProtos.put(proto.getLowerCaseName(), obj);
067: proto.registerParents(secondaryProtos, obj);
068: }
069: }
070:
071: /**
072: * Returns the number of objects in the request path.
073: */
074: public int size() {
075: return objects.size();
076: }
077:
078: /**
079: * Gets an object in the path by index.
080: *
081: * @param idx the index of the object in the request path
082: */
083: public Object get(int idx) {
084: if (idx < 0 || idx >= objects.size()) {
085: return null;
086: }
087:
088: return objects.get(idx);
089: }
090:
091: /**
092: * Gets an object in the path by prototype name.
093: *
094: * @param typeName the prototype name of the object in the request path
095: */
096: public Object getByPrototypeName(String typeName) {
097: // search primary prototypes first
098: Object obj = primaryProtos.get(typeName);
099:
100: if (obj != null) {
101: return obj;
102: }
103:
104: // if that fails, consult secondary prototype map
105: return secondaryProtos.get(typeName);
106: }
107:
108: /**
109: * Returns the string representation of this path usable for links.
110: */
111: public String href(String action)
112: throws UnsupportedEncodingException {
113: StringBuffer buffer = new StringBuffer(app.getBaseURI());
114:
115: int start = 1;
116: String hrefRootPrototype = app.getHrefRootPrototype();
117:
118: if (hrefRootPrototype != null) {
119: Object rootObject = getByPrototypeName(hrefRootPrototype);
120:
121: if (rootObject != null) {
122: start = objects.indexOf(rootObject) + 1;
123: }
124: }
125:
126: for (int i = start; i < ids.size(); i++) {
127: buffer.append(UrlEncoded.encode(ids.get(i).toString(),
128: app.charset));
129: buffer.append("/");
130: }
131:
132: if (action != null) {
133: buffer.append(UrlEncoded.encode(action, app.charset));
134: }
135:
136: return buffer.toString();
137: }
138:
139: /**
140: * Checks if the given object is contained in the request path.
141: * Itreturns the zero-based index position, or -1 if it isn't contained.
142: *
143: * @param obj the element to check
144: * @return the index of the element, or -1 if it isn't contained
145: * @deprecated use {@link #indexOf(Object)} instead.
146: */
147: public int contains(Object obj) {
148: return objects.indexOf(obj);
149: }
150:
151: /**
152: * Checks if the given object is contained in the request path.
153: * Itreturns the zero-based index position, or -1 if it isn't contained.
154: *
155: * @param obj the element to check
156: * @return the index of the element, or -1 if it isn't contained
157: */
158: public int indexOf(Object obj) {
159: return objects.indexOf(obj);
160: }
161:
162: /**
163: * Return a string representation of the Request Path
164: */
165: public String toString() {
166: // If there's just one element we're on the root object.
167: if (ids.size() <= 1)
168: return "/";
169:
170: StringBuffer buffer = new StringBuffer();
171: for (int i = 1; i < ids.size(); i++) {
172: buffer.append('/');
173: buffer.append(ids.get(i));
174: }
175: return buffer.toString();
176: }
177: }
|