001: /******************************************************************************
002: * JBoss, a division of Red Hat *
003: * Copyright 2006, Red Hat Middleware, LLC, and individual *
004: * contributors as indicated by the @authors tag. See the *
005: * copyright.txt in the distribution for a full listing of *
006: * individual contributors. *
007: * *
008: * This is free software; you can redistribute it and/or modify it *
009: * under the terms of the GNU Lesser General Public License as *
010: * published by the Free Software Foundation; either version 2.1 of *
011: * the License, or (at your option) any later version. *
012: * *
013: * This software is distributed in the hope that it will be useful, *
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of *
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
016: * Lesser General Public License for more details. *
017: * *
018: * You should have received a copy of the GNU Lesser General Public *
019: * License along with this software; if not, write to the Free *
020: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
021: * 02110-1301 USA, or see the FSF site: http://www.fsf.org. *
022: ******************************************************************************/package org.jboss.portal.theme.impl;
023:
024: import org.jboss.logging.Logger;
025: import org.jboss.portal.jems.as.system.AbstractJBossService;
026: import org.jboss.portal.theme.PortalTheme;
027: import org.jboss.portal.theme.RuntimeContext;
028: import org.jboss.portal.theme.ServerRegistrationID;
029: import org.jboss.portal.theme.ThemeException;
030: import org.jboss.portal.theme.ThemeInfo;
031: import org.jboss.portal.theme.ThemeService;
032: import org.jboss.portal.theme.metadata.PortalThemeMetaData;
033: import org.jboss.system.Service;
034:
035: import java.util.ArrayList;
036: import java.util.Collection;
037: import java.util.Collections;
038: import java.util.HashMap;
039: import java.util.Iterator;
040: import java.util.List;
041: import java.util.Map;
042: import java.util.StringTokenizer;
043:
044: /**
045: * TODO: A description of this class.
046: *
047: * @author <a href="mailto:mholzner@novell.com">Martin Holzner</a>.
048: * @version <tt>$Revision: 8784 $</tt>
049: */
050: public class ThemeServiceImpl extends AbstractJBossService implements
051: ThemeService, Service {
052:
053: private static Logger log = Logger
054: .getLogger(ThemeServiceImpl.class);
055:
056: private Map themes;
057: private Map themeNames;
058: private Map exactThemeNames;
059: private ServerRegistrationID defaultID;
060:
061: private PortalTheme defaultTheme;
062: private String defaultThemeName;
063:
064: public ThemeServiceImpl() {
065: log.debug("ThemeServiceImpl instantiated.");
066: }
067:
068: /** @throws Exception */
069: protected void createService() throws Exception {
070: log.debug("create ThemeServiceImpl ....");
071: themes = Collections.synchronizedMap(new HashMap());
072: themeNames = Collections.synchronizedMap(new HashMap());
073: exactThemeNames = Collections.synchronizedMap(new HashMap());
074: }
075:
076: protected void destroyService() {
077: log.debug("destroy ThemeServiceImpl ....");
078: themes.clear();
079: themeNames.clear();
080: exactThemeNames.clear();
081: }
082:
083: protected void startService() throws Exception {
084: log.debug("start ThemeServiceImpl ....");
085: }
086:
087: protected void stopService() {
088: log.debug("stop ThemeServiceImpl ....");
089: }
090:
091: public void addTheme(RuntimeContext runtimeContext,
092: PortalThemeMetaData metaData) throws ThemeException {
093: try {
094: log.debug("add theme: " + metaData);
095:
096: PortalTheme theme = (PortalTheme) runtimeContext
097: .getClassLoader()
098: .loadClass(metaData.getClassName()).newInstance();
099:
100: // Make sure the hash maps are initialized
101: if (themes == null) {
102: try {
103: create();
104: } catch (Exception e) {
105: throw new ThemeException(e);
106: }
107: }
108:
109: ThemeInfo info = new ThemeInfo(runtimeContext, metaData);
110: theme.init(this , info);
111:
112: if (ServerRegistrationID.TYPE_THEME.equals(info
113: .getRegistrationId().getType())) {
114:
115: themeNames.put(metaData.getName(), info
116: .getRegistrationId());
117: themes.put(info.getRegistrationId(), theme);
118:
119: String key = info.getAppId() + "." + metaData.getName();
120: exactThemeNames.put(key, info.getRegistrationId());
121: } else {
122: throw new ThemeException("wrong meta data type: "
123: + info.getRegistrationId().getType());
124: }
125: } catch (Exception e) {
126: throw new ThemeException(e);
127: }
128: }
129:
130: /** @see ThemeService#removeTheme(org.jboss.portal.theme.PortalTheme) */
131: public void removeTheme(PortalTheme theme) {
132: ServerRegistrationID themeId = theme.getThemeInfo()
133: .getRegistrationId();
134: if (themes.containsKey(themeId)) {
135: ThemeInfo info = theme.getThemeInfo();
136: theme.destroy();
137:
138: log
139: .debug("remove theme " + themeId + ": "
140: + info.getName());
141:
142: final String themeName = info.getAppId() + "."
143: + info.getName();
144: if (exactThemeNames.keySet().contains(themeName)) {
145: log.debug("removing theme exact " + themeName);
146: exactThemeNames.remove(themeName);
147: }
148: if (themeNames.keySet().contains(info.getName())) {
149: log.debug("removing theme " + info.getName());
150: themeNames.remove(info.getName());
151: }
152: themes.remove(themeId);
153:
154: // if the default was removed, set a random one
155: if (defaultID != null && defaultID.equals(themeId)) {
156: log
157: .debug("removed default theme; need to set a new default...");
158: Iterator keySet = themes.keySet().iterator();
159: if (keySet.hasNext()) {
160: defaultID = (ServerRegistrationID) keySet.next();
161: log.debug("set new default to " + defaultID);
162: } else {
163: defaultID = null;
164: }
165: }
166: }
167: }
168:
169: /** @see ThemeService#removeThemes(String) */
170: public void removeThemes(String appId) {
171: List themesToDelete = new ArrayList();
172:
173: // first get all the themes that fit the criteria (can't remove while iterating)
174: for (Iterator allThemes = themes.keySet().iterator(); allThemes
175: .hasNext();) {
176: PortalTheme theme = (PortalTheme) themes.get(allThemes
177: .next());
178: if (theme.getThemeInfo().getAppId().equals(appId)) {
179: themesToDelete.add(theme);
180: }
181: }
182:
183: // now remove them
184: for (Iterator toDelete = themesToDelete.iterator(); toDelete
185: .hasNext();) {
186: PortalTheme t = (PortalTheme) toDelete.next();
187: removeTheme(t);
188: }
189: }
190:
191: /** @see ThemeService#setDefault(org.jboss.portal.theme.ServerRegistrationID) */
192: public void setDefault(ServerRegistrationID themeId)
193: throws ThemeException {
194: log.debug("set default theme " + themeId);
195: if (themes.keySet().contains(themeId)) {
196: defaultID = themeId;
197: log.debug("set new default theme to " + defaultID);
198: return;
199: }
200: throw new ThemeException("Theme with name [" + themeId
201: + "] does not exist");
202: }
203:
204: public void setDefaultThemeName(String defaultName)
205: throws ThemeException {
206: log.debug("setting default: " + defaultName);
207: defaultThemeName = defaultName;
208: defaultTheme = null;
209: }
210:
211: public PortalTheme getDefaultTheme() {
212: if (defaultTheme == null) {
213: if (exactThemeNames.keySet().contains(defaultThemeName)) {
214: ServerRegistrationID defaultID = (ServerRegistrationID) exactThemeNames
215: .get(defaultThemeName);
216: defaultTheme = (PortalTheme) themes.get(defaultID);
217: } else if (themeNames.keySet().contains(defaultThemeName)) {
218: ServerRegistrationID defaultID = (ServerRegistrationID) themeNames
219: .get(defaultThemeName);
220: defaultTheme = (PortalTheme) themes.get(defaultID);
221: }
222: }
223: if (defaultTheme == null) {
224: log.error("Couldn't find the default layout named:"
225: + defaultThemeName);
226: }
227: return defaultTheme;
228: }
229:
230: /**
231: * Set the default theme.
232: *
233: * @param name the name of the theme that is to be set as default
234: * @throws ThemeException if the theme is not part of the available themes
235: */
236: public void setDefaultFromName(String name) throws ThemeException {
237: log.debug("set default theme " + name);
238: if (exactThemeNames.keySet().contains(name)) {
239: defaultID = (ServerRegistrationID) exactThemeNames
240: .get(name);
241: return;
242: }
243: if (themeNames.keySet().contains(name)) {
244: defaultID = (ServerRegistrationID) themeNames.get(name);
245: return;
246: }
247: throw new ThemeException("Theme with name [" + name
248: + "] does not exist");
249: }
250:
251: /** @see ThemeService#getTheme(org.jboss.portal.theme.ServerRegistrationID,boolean) */
252: public PortalTheme getTheme(ServerRegistrationID themeId,
253: boolean defaultOnNull) {
254: log.debug("get theme " + themeId);
255: if (themeId == null) {
256: throw new IllegalArgumentException(
257: "Theme ID must not be null");
258: }
259:
260: if (!themes.keySet().contains(themeId) && defaultOnNull
261: && defaultID != null) {
262: return (PortalTheme) themes.get(defaultID);
263: }
264:
265: return (PortalTheme) themes.get(themeId);
266: }
267:
268: /** @see ThemeService#getTheme(String,boolean) */
269: public PortalTheme getTheme(String name, boolean defaultOnNull) {
270: log.debug("get theme " + name);
271: if (name == null || "".equals(name)) {
272: throw new IllegalArgumentException(
273: "Name cannot be null or empty");
274: }
275:
276: if (exactThemeNames.keySet().contains(name)) {
277: log.debug("found theme exact " + name);
278: return (PortalTheme) themes.get(exactThemeNames.get(name));
279: }
280: if (themeNames.keySet().contains(name)) {
281: log.debug("found theme " + name);
282: return (PortalTheme) themes.get(themeNames.get(name));
283: } else if (defaultOnNull && defaultID != null) {
284: log.debug("returning default theme " + defaultID);
285: return (PortalTheme) themes.get(defaultID);
286: }
287:
288: log.warn("Theme with name [" + name + "] not found");
289:
290: return null;
291: }
292:
293: public PortalTheme getThemeById(String themeIdString) {
294: PortalTheme theme;
295:
296: // If the id is provided in the form of context.name then look up the theme via a registration id
297: if (themeIdString == null) {
298: theme = getDefaultTheme();
299: } else if (themeIdString.lastIndexOf(".") > 0) {
300: ServerRegistrationID themeId = ServerRegistrationID
301: .createID(ServerRegistrationID.TYPE_THEME,
302: parseId(themeIdString));
303: theme = getTheme(themeId, true);
304: } else {
305: // Otherwise use the ordinary theme name provided and lookup the theme via the name
306: theme = getTheme(themeIdString, true);
307: }
308:
309: // Last Chance
310: if (theme == null) {
311: theme = getTheme("renaissance", true);
312: }
313:
314: // We don't like that situation
315: if (theme == null) {
316: throw new IllegalStateException("No Theme found for "
317: + themeIdString);
318: }
319:
320: //
321: return theme;
322: }
323:
324: /** @see org.jboss.portal.theme.ThemeService#getThemes() */
325: public Collection getThemes() {
326: return Collections.unmodifiableCollection(themes.values());
327: }
328:
329: /** @see org.jboss.portal.theme.ThemeService#getThemeNames() */
330: public Collection getThemeNames() {
331: return Collections.unmodifiableCollection(themeNames.keySet());
332: }
333:
334: /**
335: * parse the provided String for '.' as a separator. For each token, add an entry to a String[] that will be returned
336: * as the result
337: *
338: * @param layoutIDString the string to be examined
339: * @return an array of Strings
340: */
341: public static String[] parseId(String layoutIDString) {
342: List names = new ArrayList();
343: StringTokenizer tokens = new StringTokenizer(layoutIDString,
344: ".");
345: if (tokens.countTokens() > 1) {
346: while (tokens.hasMoreElements()) {
347: names.add(tokens.nextToken());
348: }
349: } else {
350: names.add(layoutIDString);
351: }
352:
353: String[] id = new String[names.size()];
354: names.toArray(id);
355: return id;
356: }
357: }
|