001: /**
002: * (c) 2002-2004 Gareth Cronin.
003: * Subject to LGPL
004: * @author garethc
005: * Date: 5/03/2003
006: */package vqwiki;
007:
008: import org.apache.log4j.Logger;
009:
010: import javax.servlet.http.HttpServletRequest;
011: import java.io.File;
012: import java.io.FileOutputStream;
013: import java.io.IOException;
014: import java.io.InputStream;
015: import java.util.Properties;
016:
017: /**
018: * Class for controlling "pseudotopics". A pseudotopic is a topic name that maps to a redirect URL rather
019: * than a real Wiki topic. Examples are RecentChanges and SetUsername. The mappings of topic names
020: * to redirect URLs are persisted in WEB-INF/classes/pseudotopics.properties
021: * <p/>
022: * Pseudotopics can also have permanent parameters associated with them by making appropriate entries in
023: * pseudotopics.properties. E.g. the entries for ToDoWikiTopics looks like this:
024: * <pre>
025: * ToDoWikiTopics=/jsp/allTopics.jsp
026: * ToDoWikiTopics.param.0=todo=true
027: * </pre>
028: * this means that when ToDoWikiTopics is redirected to the allTopics.jsp a parameter named "todo" with
029: * the value "true" is also passed. In this way more than one pseudotopic can be mapped to a single
030: * redirect URL.
031: * <p/>
032: * Subject to LGPL
033: */
034: public class PseudoTopicHandler {
035:
036: /** Logger */
037: private static final Logger logger = Logger
038: .getLogger(PseudoTopicHandler.class);
039: /** Singleton instance */
040: private static PseudoTopicHandler instance;
041: /** Properties bundle to store mappings */
042: private Properties mapping;
043: /** Name of resource to access the persisted bundle */
044: private static final String RESOURCE_NAME = "/pseudotopics.properties";
045:
046: /**
047: * Get instance
048: *
049: * @return singleton instance
050: */
051: public synchronized static PseudoTopicHandler getInstance() {
052: if (instance == null) {
053: instance = new PseudoTopicHandler();
054: }
055: return instance;
056: }
057:
058: /**
059: * Hide constructor
060: */
061: private PseudoTopicHandler() {
062: }
063:
064: /**
065: * Add a mapping and persist it to the properties file. Used by the plugin manager for actions that
066: * need a pseudotopic.
067: *
068: * @param pseudoTopicName topic name
069: * @param redirectUrl url to redirect to
070: */
071: public void addMapping(String pseudoTopicName, String redirectUrl) {
072: logger.debug("adding mapping: " + pseudoTopicName + "->'"
073: + redirectUrl + "'");
074: getMapping().setProperty(pseudoTopicName, redirectUrl);
075: FileOutputStream fout = null;
076: try {
077: File outputFile = new File(getClass().getResource("/")
078: .getFile(), RESOURCE_NAME);
079: fout = new FileOutputStream(outputFile);
080: getMapping().store(fout, "pseudotopics");
081: } catch (IOException e) {
082: logger.error("", e);
083: } finally {
084: if (fout != null) {
085: try {
086: fout.close();
087: } catch (IOException e) {
088: logger.warn("error closing stream", e);
089: }
090: }
091: }
092: }
093:
094: /**
095: * Get the mapping, loading from persistence if necessary
096: *
097: * @return mapping
098: */
099: private Properties getMapping() {
100: if (mapping == null) {
101: mapping = new Properties();
102: InputStream in = getClass().getResourceAsStream(
103: RESOURCE_NAME);
104: if (in == null) {
105: logger.warn("No properties file found: "
106: + RESOURCE_NAME);
107: }
108: try {
109: this .mapping.load(in);
110: } catch (IOException e) {
111: logger.error("Failed to read the properties file", e);
112: }
113: }
114: return mapping;
115: }
116:
117: /**
118: * Return a redirect URL for the given topic
119: *
120: * @param pseudotopicName topic
121: * @return redirect URL or null if no mapping exists
122: */
123: public String getRedirectURL(String pseudotopicName) {
124: String redirectURL = getMapping().getProperty(pseudotopicName);
125: String msg = ((redirectURL == null) ? "no pseudotopic redirect for "
126: + pseudotopicName
127: : "pseudo topic found for " + pseudotopicName + ": "
128: + redirectURL);
129: logger.debug(msg);
130: return redirectURL;
131: }
132:
133: /**
134: * Return true if there is a mapping for the given topic
135: *
136: * @param pseudotopicName topic
137: * @return true if mapping exists
138: */
139: public boolean isPseudoTopic(String pseudotopicName) {
140: return getRedirectURL(pseudotopicName) != null;
141: }
142:
143: /**
144: * Add parameters defined in the mapping to the servlet request
145: *
146: * @param pseudotopicName topic name
147: * @param request incoming request
148: */
149: public void setAttributes(String pseudotopicName,
150: HttpServletRequest request) {
151: for (int i = 0;; i++) {
152: StringBuffer buffer = new StringBuffer();
153: buffer.append(pseudotopicName);
154: buffer.append(".param.");
155: buffer.append(i);
156: String pair = getMapping().getProperty(buffer.toString());
157: if (pair == null) {
158: break;
159: }
160: logger.debug("setting attribute on " + pseudotopicName
161: + ": " + pair);
162: request.setAttribute(pair.substring(0, pair.indexOf('=')),
163: pair.substring(pair.indexOf("=") - 1));
164: }
165: if ("SetUsername".equals(pseudotopicName)) {
166: try {
167: request.setAttribute("userList", WikiBase.getInstance()
168: .getUsergroupInstance().getListOfAllUsers());
169: } catch (Exception e) {
170: }
171: }
172: }
173: }
|