1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.exoplatform.services.wcm.skin;
18
19 import java.net.URL;
20 import java.util.Collection;
21 import java.util.HashMap;
22 import java.util.HashSet;
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Map.Entry;
27
28 import javax.jcr.Node;
29 import javax.jcr.RepositoryException;
30 import javax.servlet.ServletContext;
31
32 import org.apache.commons.httpclient.methods.GetMethod;
33 import org.apache.commons.lang.StringUtils;
34
35
36 import org.exoplatform.container.PortalContainer;
37 import org.exoplatform.container.RootContainer.PortalContainerPostCreateTask;
38 import org.exoplatform.container.RootContainer.PortalContainerInitTask;
39 import org.exoplatform.portal.resource.SkinConfig;
40 import org.exoplatform.portal.resource.SkinKey;
41 import org.exoplatform.portal.resource.SkinService;
42 import org.exoplatform.portal.resource.SkinVisitor;
43
44 import org.exoplatform.services.jcr.RepositoryService;
45 import org.exoplatform.services.jcr.ext.common.SessionProvider;
46 import org.exoplatform.services.log.ExoLogger;
47 import org.exoplatform.services.log.Log;
48 import org.exoplatform.services.wcm.core.WCMConfigurationService;
49 import org.exoplatform.services.wcm.portal.LivePortalManagerService;
50 import org.exoplatform.services.wcm.utils.WCMCoreUtils;
51 import org.gatein.wci.WebApp;
52 import org.picocontainer.Startable;
53
54
55
56
57
58 public class XSkinService implements Startable {
59
60 final static String SEPARATOR = "/";
61 final static String MODULE_NAME_PATTERN = "{repositoryName}"+SEPARATOR+"{portalName}";
62 final static String MODULE_NAME_REGEXP = "(.*)"+SEPARATOR+"(.*)";
63 final static String MODULE_PARAM = "moduleName";
64 final static String SKIN_PARAM = "skinName";
65 final static String CONTEXT_PARAM = "context";
66 final static String SITENAME_PARAM = "siteName";
67
68
69 public final static String SKIN_PATH_REGEXP = "/(.*)/css/jcr/"+MODULE_NAME_REGEXP+"/(.*)/(.*).css";
70
71
72 private final static String SKIN_PATH_PATTERN = "/{docBase}/css/jcr/{moduleName}/(.*)/Stylesheet.css";
73
74
75 private static final Log LOG = ExoLogger.getLogger(XSkinService.class.getName());
76
77
78 private WCMConfigurationService configurationService;
79
80
81 private SkinService skinService ;
82
83
84 private ServletContext servletContext;
85
86
87
88
89
90
91
92 public XSkinService(LivePortalManagerService livePortalService) throws Exception {
93 this.skinService = WCMCoreUtils.getService(SkinService.class);
94 this.skinService.addResourceResolver(new WCMSkinResourceResolver(this.skinService, livePortalService));
95 this.configurationService = WCMCoreUtils.getService(WCMConfigurationService.class);
96 this.servletContext = WCMCoreUtils.getService(ServletContext.class);
97 }
98
99
100
101
102
103
104
105
106 public String getActiveStylesheet(Node webcontent) throws Exception {
107 return WCMCoreUtils.getActiveStylesheet(webcontent);
108 }
109
110
111
112
113
114
115
116
117
118 public void updatePortalSkinOnModify(Node portal, Node cssFile) throws Exception {
119 String sharedPortalName = configurationService.getSharedPortalName();
120 if (sharedPortalName.equals(portal.getName())) {
121 addSharedPortalSkin(portal);
122 } else {
123 addPortalSkin(portal);
124 }
125 }
126
127
128
129
130
131
132
133
134
135 public void updatePortalSkinOnRemove(Node portal, Node cssFile) throws Exception {
136 updatePortalSkinOnModify(portal, cssFile);
137 }
138
139
140
141
142
143
144
145
146 private void addPortalSkin(Node portalNode) throws Exception {
147 String moduleName = createModuleName(portalNode.getName());
148 String skinPath = StringUtils.replaceOnce(SKIN_PATH_PATTERN, "{moduleName}",moduleName)
149 .replaceFirst("\\{docBase\\}",
150 servletContext.getServletContextName());
151 Iterator<String> iterator = skinService.getAvailableSkinNames().iterator();
152 if (iterator.hasNext() == false) {
153 skinPath = StringUtils.replaceOnce(skinPath,"(.*)", "Default");
154 skinService.invalidateCachedSkin(skinPath);
155 skinService.addSkin(moduleName, "Default", skinPath);
156 } else {
157 while (iterator.hasNext()) {
158 String skinName = iterator.next();
159 skinPath = StringUtils.replaceOnce(skinPath,"(.*)",skinName);
160 skinService.invalidateCachedSkin(skinPath);
161 skinService.addSkin(moduleName, skinName, skinPath);
162 }
163 }
164 }
165
166
167
168
169
170
171
172
173 private void addSharedPortalSkin(Node portalNode) throws Exception {
174 String moduleName = createModuleName(portalNode.getName());
175 String skinPath = StringUtils.replaceOnce(SKIN_PATH_PATTERN, "{moduleName}", moduleName)
176 .replaceFirst("\\{docBase\\}",
177 servletContext.getServletContextName());
178 for (Iterator<String> iterator = skinService.getAvailableSkinNames().iterator(); iterator.hasNext();) {
179 String skinName = iterator.next();
180 skinPath = StringUtils.replaceOnce(skinPath, "(.*)", skinName);
181 skinService.invalidateCachedSkin(skinPath);
182 skinService.addPortalSkin(moduleName, skinName, skinPath);
183 }
184 }
185
186
187
188
189 public void start() {
190
191
192
193
194
195 final PortalContainerPostCreateTask task = new PortalContainerPostCreateTask() {
196 public void execute(ServletContext context, PortalContainer portalContainer) {
197 SessionProvider sessionProvider = SessionProvider.createSystemProvider();
198 try {
199 LivePortalManagerService livePortalManagerService = portalContainer.getComponentInstanceOfType(LivePortalManagerService.class);
200 List<Node> livePortals = livePortalManagerService.getLivePortals(sessionProvider);
201 for (Node portal : livePortals) {
202 addPortalSkin(portal);
203 }
204 Node sharedPortal = livePortalManagerService.getLiveSharedPortal(sessionProvider);
205 addSharedPortalSkin(sharedPortal);
206 } catch (Exception e) {
207 if (LOG.isErrorEnabled()) {
208 LOG.error("Exception when start XSkinService", e);
209 }
210 } finally {
211 sessionProvider.close();
212 }
213 }
214 };
215 PortalContainer.addInitTask(this.servletContext, task, null);
216 }
217
218
219
220
221 public void stop() {
222 }
223
224 static String createModuleName(String siteName){
225 String repoName;
226 try{
227 repoName = WCMCoreUtils.getRepository().getConfiguration().getName();
228 }catch(NullPointerException e){
229 repoName = WCMCoreUtils.getService(RepositoryService.class).getConfig().getDefaultRepositoryName();
230 }
231 String moduleName = StringUtils.replaceOnce(MODULE_NAME_PATTERN, "{repositoryName}", repoName);
232 moduleName = StringUtils.replaceOnce(moduleName,"{portalName}",siteName);
233 return moduleName;
234 }
235
236 static Map<String,String> getSkinParams(String path){
237 if (!path.matches(SKIN_PATH_REGEXP)) return null;
238 String moduleName;
239 String skinName;
240 String siteName;
241 String context;
242 String[] elements = path.split("/");
243 if (XSkinService.SEPARATOR.equals("/")){
244 context = elements[4];
245 siteName = elements[5];
246 skinName = elements[6];
247 }else{
248 context = elements[4].split(XSkinService.SEPARATOR)[0];
249 siteName = elements[4].split(XSkinService.SEPARATOR)[1];
250 skinName = elements[5];
251 }
252
253 moduleName = StringUtils.replaceOnce(MODULE_NAME_PATTERN, "{repositoryName}", context);
254 moduleName = StringUtils.replaceOnce(moduleName,"{portalName}",siteName);
255 Map<String,String> params = new HashMap<String,String>();
256 params.put(MODULE_PARAM, moduleName);
257 params.put(SKIN_PARAM, skinName);
258 params.put(SITENAME_PARAM, siteName);
259 params.put(CONTEXT_PARAM, context);
260 return params;
261 }
262
263
264 }