1 package org
.argeo
.cms
.util
;
3 import java
.io
.IOException
;
4 import java
.io
.InputStream
;
5 import java
.util
.ArrayList
;
6 import java
.util
.Arrays
;
7 import java
.util
.HashMap
;
8 import java
.util
.Hashtable
;
9 import java
.util
.LinkedHashMap
;
10 import java
.util
.List
;
13 import javax
.jcr
.Repository
;
14 import javax
.jcr
.RepositoryException
;
15 import javax
.jcr
.Session
;
16 import javax
.jcr
.security
.Privilege
;
17 import javax
.jcr
.version
.VersionManager
;
19 import org
.apache
.commons
.logging
.Log
;
20 import org
.apache
.commons
.logging
.LogFactory
;
21 import org
.argeo
.cms
.CmsConstants
;
22 import org
.argeo
.cms
.CmsException
;
23 import org
.argeo
.cms
.CmsUiProvider
;
24 import org
.argeo
.cms
.LifeCycleUiProvider
;
25 import org
.argeo
.jcr
.JcrUtils
;
26 import org
.eclipse
.rap
.rwt
.RWT
;
27 import org
.eclipse
.rap
.rwt
.application
.Application
;
28 import org
.eclipse
.rap
.rwt
.application
.Application
.OperationMode
;
29 import org
.eclipse
.rap
.rwt
.application
.ApplicationConfiguration
;
30 import org
.eclipse
.rap
.rwt
.application
.EntryPoint
;
31 import org
.eclipse
.rap
.rwt
.application
.EntryPointFactory
;
32 import org
.eclipse
.rap
.rwt
.application
.ExceptionHandler
;
33 import org
.eclipse
.rap
.rwt
.client
.WebClient
;
34 import org
.eclipse
.rap
.rwt
.client
.service
.JavaScriptExecutor
;
35 import org
.eclipse
.rap
.rwt
.service
.ResourceLoader
;
36 import org
.eclipse
.swt
.SWT
;
37 import org
.eclipse
.swt
.events
.SelectionAdapter
;
38 import org
.eclipse
.swt
.events
.SelectionEvent
;
39 import org
.eclipse
.swt
.layout
.FillLayout
;
40 import org
.eclipse
.swt
.widgets
.Button
;
41 import org
.eclipse
.swt
.widgets
.Composite
;
42 import org
.osgi
.framework
.BundleContext
;
43 import org
.osgi
.framework
.ServiceRegistration
;
45 /** A basic generic app based on {@link SimpleErgonomics}. */
46 public class SimpleApp
implements CmsConstants
, ApplicationConfiguration
{
47 private final static Log log
= LogFactory
.getLog(SimpleApp
.class);
49 private String contextName
= null;
51 private Map
<String
, Map
<String
, String
>> branding
= new HashMap
<String
, Map
<String
, String
>>();
52 private Map
<String
, List
<String
>> styleSheets
= new HashMap
<String
, List
<String
>>();
54 private List
<String
> resources
= new ArrayList
<String
>();
56 private BundleContext bundleContext
;
58 private Repository repository
;
59 private String workspace
= null;
60 private String jcrBasePath
= "/";
61 private List
<String
> roPrincipals
= Arrays
.asList("anonymous", "everyone");
62 private List
<String
> rwPrincipals
= Arrays
.asList("everyone");
64 private CmsUiProvider header
;
65 private Map
<String
, CmsUiProvider
> pages
= new LinkedHashMap
<String
, CmsUiProvider
>();
67 private Integer headerHeight
= 40;
69 private ServiceRegistration
<ApplicationConfiguration
> appReg
;
71 public void configure(Application application
) {
73 StyleSheetResourceLoader styleSheetRL
= new StyleSheetResourceLoader(
75 BundleResourceLoader bundleRL
= new BundleResourceLoader(
78 application
.setOperationMode(OperationMode
.SWT_COMPATIBILITY
);
79 // application.setOperationMode(OperationMode.JEE_COMPATIBILITY);
81 application
.setExceptionHandler(new CmsExceptionHandler());
83 // loading animated gif
84 application
.addResource(LOADING_IMAGE
,
85 createResourceLoader(LOADING_IMAGE
));
87 application
.addResource(NO_IMAGE
, createResourceLoader(NO_IMAGE
));
89 for (String resource
: resources
) {
90 application
.addResource(resource
, bundleRL
);
91 if (log
.isDebugEnabled())
92 log
.debug("Resource " + resource
);
95 Map
<String
, String
> defaultBranding
= null;
96 if (branding
.containsKey("*"))
97 defaultBranding
= branding
.get("*");
100 for (String page
: pages
.keySet()) {
101 Map
<String
, String
> properties
= defaultBranding
!= null ?
new HashMap
<String
, String
>(
102 defaultBranding
) : new HashMap
<String
, String
>();
103 if (branding
.containsKey(page
)) {
104 properties
.putAll(branding
.get(page
));
107 if (properties
.containsKey(WebClient
.FAVICON
)) {
108 String faviconRelPath
= properties
.get(WebClient
.FAVICON
);
109 application
.addResource(faviconRelPath
,
110 new BundleResourceLoader(bundleContext
));
111 if (log
.isTraceEnabled())
112 log
.trace("Favicon " + faviconRelPath
);
117 if (!properties
.containsKey(WebClient
.PAGE_TITLE
)) {
118 if (page
.length() > 0)
120 WebClient
.PAGE_TITLE
,
121 Character
.toUpperCase(page
.charAt(0))
122 + page
.substring(1));
126 if (!properties
.containsKey(WebClient
.BODY_HTML
))
127 properties
.put(WebClient
.BODY_HTML
, DEFAULT_LOADING_BODY
);
132 application
.addEntryPoint("/" + page
, new CmsEntryPointFactory(
133 pages
.get(page
), repository
, workspace
, properties
),
135 log
.info("Page /" + page
);
139 for (String themeId
: styleSheets
.keySet()) {
140 List
<String
> cssLst
= styleSheets
.get(themeId
);
141 if (log
.isDebugEnabled())
142 log
.debug("Theme " + themeId
);
143 for (String css
: cssLst
) {
144 application
.addStyleSheet(themeId
, css
, styleSheetRL
);
145 if (log
.isDebugEnabled())
146 log
.debug(" CSS " + css
);
150 } catch (RuntimeException e
) {
151 // Easier access to initialisation errors
152 log
.error("Unexpected exception when configuring RWT application.",
158 public void init() throws RepositoryException
{
159 Session session
= null;
161 session
= JcrUtils
.loginOrCreateWorkspace(repository
, workspace
);
162 VersionManager vm
= session
.getWorkspace().getVersionManager();
163 if (!vm
.isCheckedOut("/"))
165 JcrUtils
.mkdirs(session
, jcrBasePath
);
166 for (String principal
: rwPrincipals
)
167 JcrUtils
.addPrivilege(session
, jcrBasePath
, principal
,
168 Privilege
.JCR_WRITE
);
169 for (String principal
: roPrincipals
)
170 JcrUtils
.addPrivilege(session
, jcrBasePath
, principal
,
173 for (String pageName
: pages
.keySet()) {
175 initPage(session
, pages
.get(pageName
));
177 } catch (Exception e
) {
178 throw new CmsException(
179 "Cannot initialize page " + pageName
, e
);
184 JcrUtils
.logoutQuietly(session
);
191 protected void initPage(Session adminSession
, CmsUiProvider page
)
192 throws RepositoryException
{
193 if (page
instanceof LifeCycleUiProvider
)
194 ((LifeCycleUiProvider
) page
).init(adminSession
);
197 public void destroy() {
198 for (String pageName
: pages
.keySet()) {
200 CmsUiProvider page
= pages
.get(pageName
);
201 if (page
instanceof LifeCycleUiProvider
)
202 ((LifeCycleUiProvider
) page
).destroy();
203 } catch (Exception e
) {
204 log
.error("Cannot destroy page " + pageName
, e
);
209 protected void register() {
210 Hashtable
<String
, String
> props
= new Hashtable
<String
, String
>();
211 if (contextName
!= null)
212 props
.put("contextName", contextName
);
213 appReg
= bundleContext
.registerService(ApplicationConfiguration
.class,
215 if (log
.isDebugEnabled())
216 log
.debug("Registered " + (contextName
== null ?
"/" : contextName
));
219 protected void unregister() {
221 if (log
.isDebugEnabled())
222 log
.debug("Unregistered "
223 + (contextName
== null ?
"/" : contextName
));
226 public void setRepository(Repository repository
) {
227 this.repository
= repository
;
230 public void setWorkspace(String workspace
) {
231 this.workspace
= workspace
;
234 public void setHeader(CmsUiProvider header
) {
235 this.header
= header
;
238 public void setPages(Map
<String
, CmsUiProvider
> pages
) {
242 public void setJcrBasePath(String basePath
) {
243 this.jcrBasePath
= basePath
;
246 public void setRoPrincipals(List
<String
> roPrincipals
) {
247 this.roPrincipals
= roPrincipals
;
250 public void setRwPrincipals(List
<String
> rwPrincipals
) {
251 this.rwPrincipals
= rwPrincipals
;
254 public void setHeaderHeight(Integer headerHeight
) {
255 this.headerHeight
= headerHeight
;
258 public void setBranding(Map
<String
, Map
<String
, String
>> branding
) {
259 this.branding
= branding
;
262 public void setStyleSheets(Map
<String
, List
<String
>> styleSheets
) {
263 this.styleSheets
= styleSheets
;
266 public void setBundleContext(BundleContext bundleContext
) {
267 this.bundleContext
= bundleContext
;
270 public void setResources(List
<String
> resources
) {
271 this.resources
= resources
;
274 class CmsExceptionHandler
implements ExceptionHandler
{
277 public void handleException(Throwable throwable
) {
278 CmsUtils
.getCmsView().exception(throwable
);
283 private class CmsEntryPointFactory
implements EntryPointFactory
{
284 private final CmsUiProvider page
;
285 private final Repository repository
;
286 private final String workspace
;
287 private final Map
<String
, String
> properties
;
289 public CmsEntryPointFactory(CmsUiProvider page
, Repository repository
,
290 String workspace
, Map
<String
, String
> properties
) {
292 this.repository
= repository
;
293 this.workspace
= workspace
;
294 this.properties
= properties
;
298 public EntryPoint
create() {
299 SimpleErgonomics entryPoint
= new SimpleErgonomics(repository
,
300 workspace
, jcrBasePath
, page
, properties
) {
303 protected void createAdminArea(Composite parent
) {
304 Composite adminArea
= new Composite(parent
, SWT
.NONE
);
305 adminArea
.setLayout(new FillLayout());
306 Button refresh
= new Button(adminArea
, SWT
.PUSH
);
307 refresh
.setText("Reload App");
308 refresh
.addSelectionListener(new SelectionAdapter() {
309 private static final long serialVersionUID
= -7671999525536351366L;
312 public void widgetSelected(SelectionEvent e
) {
313 long timeBeforeReload
= 1000;
315 .getService(JavaScriptExecutor
.class)
317 "setTimeout(function() { "
318 + "location.reload();"
319 + "}," + timeBeforeReload
326 // entryPoint.setState("");
327 entryPoint
.setHeader(header
);
328 entryPoint
.setHeaderHeight(headerHeight
);
329 // CmsSession.current.set(entryPoint);
333 private void reloadApp() {
334 new Thread("Refresh app") {
344 private static ResourceLoader
createResourceLoader(final String resourceName
) {
345 return new ResourceLoader() {
346 public InputStream
getResourceAsStream(String resourceName
)
348 return getClass().getClassLoader().getResourceAsStream(
354 // private static ResourceLoader createUrlResourceLoader(final URL url) {
355 // return new ResourceLoader() {
356 // public InputStream getResourceAsStream(String resourceName)
357 // throws IOException {
358 // return url.openStream();
366 private static String DEFAULT_LOADING_BODY
= "<div"
367 + " style=\"position: absolute; left: 50%; top: 50%; margin: -32px -32px; width: 64px; height:64px\">"
368 + "<img src=\"./rwt-resources/" + LOADING_IMAGE
369 + "\" width=\"32\" height=\"32\" style=\"margin: 16px 16px\"/>"