001: /*
002: * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions
006: * are met:
007: *
008: * - Redistributions of source code must retain the above copyright
009: * notice, this list of conditions and the following disclaimer.
010: *
011: * - Redistribution in binary form must reproduce the above copyright
012: * notice, this list of conditions and the following disclaimer in
013: * the documentation and/or other materials provided with the
014: * distribution.
015: *
016: * Neither the name of Sun Microsystems, Inc. or the names of
017: * contributors may be used to endorse or promote products derived
018: * from this software without specific prior written permission.
019: *
020: * This software is provided "AS IS," without a warranty of any
021: * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
022: * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
023: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
024: * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES
025: * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
026: * DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
027: * OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
028: * FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
029: * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
030: * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE,
031: * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
032: *
033: * You acknowledge that Software is not designed, licensed or intended
034: * any nuclear facility.
035: */
036:
037: package com.sun.portal.community.template.impl;
038:
039: import java.io.File;
040: import java.io.IOException;
041: import java.io.FileInputStream;
042: import java.io.ByteArrayInputStream;
043: import java.io.FileOutputStream;
044: import java.io.BufferedReader;
045: import java.io.FileReader;
046: import java.io.FileFilter;
047: import java.io.FilenameFilter;
048: import java.io.FileNotFoundException;
049: import java.io.UnsupportedEncodingException;
050:
051: import java.net.URL;
052: import java.net.URI;
053: import java.net.URISyntaxException;
054:
055: import java.util.Properties;
056: import java.util.Iterator;
057: import java.util.Set;
058: import java.util.Map;
059: import java.util.HashSet;
060: import java.util.HashMap;
061: import java.util.TreeSet;
062: import java.util.Collections;
063: import java.util.Enumeration;
064: import java.util.StringTokenizer;
065: import java.util.Locale;
066: import java.util.ResourceBundle;
067:
068: import com.sun.portal.util.ResourceLoader;
069:
070: import com.sun.portal.community.mc.CMCRolePrincipal;
071:
072: import com.sun.portal.community.template.Template;
073: import com.sun.portal.community.template.TemplateDescriptor;
074: import com.sun.portal.community.template.TemplateException;
075: import com.sun.portal.community.template.TemplateManager;
076: import com.sun.portal.community.template.TemplateManagerFactory;
077:
078: import com.sun.portal.desktop.encode.Encoder;
079: import com.sun.portal.desktop.encode.EncoderClassNames;
080: import com.sun.portal.desktop.encode.EncoderException;
081:
082: public class CommunityTemplateManagerImpl implements TemplateManager {
083:
084: public static final String ROLE_TEMPLATE_FILE_EXTENSION = ".xml";
085: public static final String ADMIN_ROLE_TEMPLATE_FILE = CMCRolePrincipal.OWNER_ROLE
086: .toString()
087: + ROLE_TEMPLATE_FILE_EXTENSION;
088: public static final String MEMBER_ROLE_TEMPLATE_FILE = CMCRolePrincipal.MEMBER_ROLE
089: .toString()
090: + ROLE_TEMPLATE_FILE_EXTENSION;
091: public static final String VISITOR_ROLE_TEMPLATE_FILE = CMCRolePrincipal.VISITOR_ROLE
092: .toString()
093: + ROLE_TEMPLATE_FILE_EXTENSION;
094:
095: private ResourceLoader _rl = null;
096: private File _templatesDir = null;
097:
098: public CommunityTemplateManagerImpl() {
099: }
100:
101: public void init() throws TemplateException {
102:
103: _rl = ResourceLoader.getInstance(System.getProperties());
104: _templatesDir = getTemplatesDir(null);
105: }
106:
107: public void init(String portalId) throws TemplateException {
108:
109: _rl = ResourceLoader.getInstance(portalId);
110: _templatesDir = getTemplatesDir(portalId);
111: }
112:
113: public TemplateDescriptor getTemplateDescriptor(String templateId,
114: Locale locale) throws TemplateException {
115:
116: //
117: // todo: no caching implemented for now.
118: //
119:
120: java.net.URLClassLoader ucl = null;
121: try {
122: URL[] urls = { _templatesDir.toURL() };
123: ucl = java.net.URLClassLoader.newInstance(urls);
124: } catch (java.net.MalformedURLException mue) {
125: throw new TemplateException(
126: "CommunityTemplateManagerImpl.getTemplateDescriptor(): ",
127: mue);
128: }
129: ResourceBundle rb = ResourceBundle.getBundle(templateId,
130: locale, ucl);
131:
132: if (rb == null) {
133: throw new TemplateException(
134: "CommunityTemplateManagerImpl.getTemplateDescriptor(): no resource bundle found for templateId="
135: + templateId);
136: }
137:
138: TemplateDescriptor td = new CommunityTemplateDescriptorImpl(
139: templateId, rb);
140:
141: return td;
142: }
143:
144: public Template getTemplate(String templateId, Map tokenMappings)
145: throws TemplateException {
146:
147: Map roleTemplates = loadRoleTemplates(templateId);
148:
149: //
150: // replace tokens then convert to byte array
151: // todo: room for optimization. templates can be read off as
152: // byte and also perform token replace in one shot?!?
153: //
154: try {
155: for (Iterator i = roleTemplates.keySet().iterator(); i
156: .hasNext();) {
157: String role = (String) i.next();
158: String roleTemplate = (String) roleTemplates.get(role);
159: Map tokenMapping = (Map) tokenMappings.get(role);
160: roleTemplate = replaceTokens(roleTemplate, tokenMapping);
161: roleTemplates.put(role, roleTemplate.getBytes("UTF-8"));
162: }
163: } catch (UnsupportedEncodingException uee) {
164: throw new TemplateException(
165: "CommunityTemplateManagerImpl.getTemplate(): ", uee);
166: }
167:
168: Template t = new CommunityTemplateImpl(templateId,
169: roleTemplates);
170:
171: return t;
172: }
173:
174: public Set getAllTemplateIds() throws TemplateException {
175:
176: //
177: // todo: cache?
178: //
179:
180: //
181: // list all community templates directory
182: //
183: File[] templateDirs = _templatesDir.listFiles(new FileFilter() {
184: public boolean accept(File filePath) {
185: return filePath.isDirectory();
186: }
187: });
188:
189: //
190: // convert array into an ordered set (natural order)
191: //
192: TreeSet idSet = new TreeSet();
193:
194: if (templateDirs != null) {
195: for (int i = 0; i < templateDirs.length; i++) {
196: idSet.add(templateDirs[i].getName());
197: }
198: }
199:
200: return idSet;
201: }
202:
203: private Map loadRoleTemplates(String templateId)
204: throws TemplateException {
205:
206: //
207: // todo: cache?
208: //
209:
210: //
211: // collect role template files
212: //
213: File templateDir = new File(_templatesDir + File.separator
214: + templateId);
215:
216: File[] roleTemplateFiles = templateDir
217: .listFiles(new FilenameFilter() {
218: public boolean accept(File dir, String name) {
219: return name
220: .endsWith(ROLE_TEMPLATE_FILE_EXTENSION);
221: }
222: });
223:
224: //
225: // if there are no role templates, raise an error
226: //
227: if (roleTemplateFiles == null || roleTemplateFiles.length == 0) {
228: throw new TemplateException(
229: "CommunityTemplateManagerImpl.loadRoleTemplates(): no role templates are found for templateId="
230: + templateId);
231: }
232:
233: //
234: // validate role template files and build template map
235: //
236: Map roleTemplates = new HashMap();
237: for (int i = 0; i < roleTemplateFiles.length; i++) {
238: File roleTemplateFile = roleTemplateFiles[i];
239: String roleTemplateFilename = roleTemplateFile.getName();
240: int idx = roleTemplateFilename
241: .lastIndexOf(ROLE_TEMPLATE_FILE_EXTENSION);
242: String role = roleTemplateFilename.substring(0, idx);
243: CMCRolePrincipal rolePrincipal = CMCRolePrincipal
244: .valueOf(role);
245: if (rolePrincipal == null) {
246: // todo: perhaps, we need to handle this more gracefully
247: throw new TemplateException(
248: "CommunityTemplateManagerImpl.loadRoleTemplates(): Invalid role="
249: + role);
250: }
251: roleTemplates.put(role, readFile(roleTemplateFile
252: .getAbsolutePath()));
253: }
254:
255: return roleTemplates;
256: }
257:
258: private String replaceTokens(String template, Map tokenMapping) {
259:
260: Set tokens = tokenMapping.keySet();
261: for (Iterator i = tokenMapping.keySet().iterator(); i.hasNext();) {
262: String token = (String) i.next();
263: String value = (String) tokenMapping.get(token);
264: try {
265: value = Encoder.encode(EncoderClassNames.ENCODER_XML,
266: value);
267: } catch (EncoderException ee) {
268: //if value cannot be encoded, just use it.
269: }
270: template = template.replaceAll(token, value);
271: }
272:
273: return template;
274: }
275:
276: private String readFile(String filename) throws TemplateException {
277:
278: String content = null;
279: FileInputStream fis = null;
280:
281: try {
282: fis = new FileInputStream(filename);
283: byte[] bytes = new byte[fis.available()];
284: fis.read(bytes);
285: content = new String(bytes, "UTF-8");
286:
287: } catch (FileNotFoundException fnfe) {
288: throw new TemplateException(
289: "CommunityTemplateManagerImpl.readFile(): ", fnfe);
290:
291: } catch (IOException ioe) {
292: throw new TemplateException(
293: "CommunityTemplateManagerImpl.readFile(): ", ioe);
294:
295: } finally {
296: try {
297: if (fis != null) {
298: fis.close();
299: }
300:
301: } catch (IOException ioe) {
302: throw new TemplateException(
303: "CommunityTemplateManagerImpl.readFile(): ",
304: ioe);
305: }
306: }
307:
308: return content;
309: }
310:
311: private File getTemplatesDir(String portalId)
312: throws TemplateException {
313:
314: Properties psConfig = null;
315: try {
316: psConfig = _rl.getProperties("PSConfig.properties");
317: } catch (FileNotFoundException fnfe) {
318: throw new TemplateException(
319: "CommunityTemplateManagerImpl.getTemplatesDir(): ",
320: fnfe);
321: } catch (IOException ioe) {
322: throw new TemplateException(
323: "CommunityTemplateManagerImpl.getTemplatesDir(): ",
324: ioe);
325: }
326:
327: String psDataDir = psConfig.getProperty("ps.data.location", "");
328:
329: StringBuffer templatesDirPath = new StringBuffer();
330: templatesDirPath.append(psDataDir + File.separator);
331: templatesDirPath.append("portals" + File.separator);
332: //System.out.println("templateDirPath.part1=" + templatesDirPath.toString());
333: //System.out.println("portalId=" + _rl.getPortalId());
334: templatesDirPath.append((portalId == null) ? _rl.getPortalId()
335: : portalId);
336: templatesDirPath.append(File.separator + "communitytemplates");
337:
338: return new File(templatesDirPath.toString());
339: }
340: }
|