3 import java
.io
.IOException
;
4 import java
.io
.InputStream
;
5 import java
.io
.PrintWriter
;
6 import java
.io
.StringWriter
;
7 import java
.util
.ArrayList
;
8 import java
.util
.Arrays
;
9 import java
.util
.HashMap
;
10 import java
.util
.LinkedHashMap
;
11 import java
.util
.List
;
14 import javax
.jcr
.Node
;
15 import javax
.jcr
.Repository
;
16 import javax
.jcr
.RepositoryException
;
17 import javax
.jcr
.Session
;
18 import javax
.jcr
.security
.Privilege
;
19 import javax
.jcr
.version
.VersionManager
;
21 import org
.apache
.commons
.io
.IOUtils
;
22 import org
.apache
.commons
.logging
.Log
;
23 import org
.apache
.commons
.logging
.LogFactory
;
24 import org
.argeo
.cms
.internal
.ImageManagerImpl
;
25 import org
.argeo
.cms
.util
.CmsUtils
;
26 import org
.argeo
.jcr
.JcrUtils
;
27 import org
.eclipse
.gemini
.blueprint
.context
.BundleContextAware
;
28 import org
.eclipse
.rap
.rwt
.RWT
;
29 import org
.eclipse
.rap
.rwt
.application
.Application
;
30 import org
.eclipse
.rap
.rwt
.application
.Application
.OperationMode
;
31 import org
.eclipse
.rap
.rwt
.application
.ApplicationConfiguration
;
32 import org
.eclipse
.rap
.rwt
.application
.EntryPoint
;
33 import org
.eclipse
.rap
.rwt
.application
.EntryPointFactory
;
34 import org
.eclipse
.rap
.rwt
.application
.ExceptionHandler
;
35 import org
.eclipse
.rap
.rwt
.client
.WebClient
;
36 import org
.eclipse
.rap
.rwt
.service
.ResourceLoader
;
37 import org
.eclipse
.swt
.SWT
;
38 import org
.eclipse
.swt
.layout
.FillLayout
;
39 import org
.eclipse
.swt
.layout
.GridData
;
40 import org
.eclipse
.swt
.widgets
.Composite
;
41 import org
.eclipse
.swt
.widgets
.Control
;
42 import org
.eclipse
.swt
.widgets
.Label
;
43 import org
.eclipse
.swt
.widgets
.Text
;
44 import org
.osgi
.framework
.BundleContext
;
46 /** Configures an Argeo CMS RWT application. */
47 public class CmsApplication
implements CmsConstants
, ApplicationConfiguration
,
49 final static Log log
= LogFactory
.getLog(CmsApplication
.class);
51 // private Map<String, EntryPointFactory> entryPoints = new HashMap<String,
52 // EntryPointFactory>();
53 private Map
<String
, Map
<String
, String
>> branding
= new HashMap
<String
, Map
<String
, String
>>();
54 private Map
<String
, List
<String
>> styleSheets
= new HashMap
<String
, List
<String
>>();
56 private List
<String
> resources
= new ArrayList
<String
>();
58 // private Bundle clientScriptingBundle;
59 private BundleContext bundleContext
;
61 private Repository repository
;
62 private String workspace
= null;
63 private String basePath
= "/";
64 private List
<String
> roPrincipals
= Arrays
.asList("anonymous", "everyone");
65 private List
<String
> rwPrincipals
= Arrays
.asList("everyone");
67 private CmsLogin cmsLogin
;
69 private CmsUiProvider header
;
70 private Map
<String
, CmsUiProvider
> pages
= new LinkedHashMap
<String
, CmsUiProvider
>();
72 private Integer headerHeight
= 40;
75 private CmsImageManager imageManager
= new ImageManagerImpl();
77 public void configure(Application application
) {
79 application
.setOperationMode(OperationMode
.SWT_COMPATIBILITY
);
80 application
.setExceptionHandler(new CmsExceptionHandler());
82 // TODO load all pics under icons
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
, new BundleResourceLoader(
92 if (log
.isDebugEnabled())
93 log
.debug("Registered resource " + resource
);
96 Map
<String
, String
> defaultBranding
= null;
97 if (branding
.containsKey("*"))
98 defaultBranding
= branding
.get("*");
101 for (String page
: pages
.keySet()) {
102 Map
<String
, String
> properties
= defaultBranding
!= null ?
new HashMap
<String
, String
>(
103 defaultBranding
) : new HashMap
<String
, String
>();
104 if (branding
.containsKey(page
)) {
105 properties
.putAll(branding
.get(page
));
108 if (properties
.containsKey(WebClient
.FAVICON
)) {
109 String faviconRelPath
= properties
.get(WebClient
.FAVICON
);
110 application
.addResource(faviconRelPath
,
111 new BundleResourceLoader(bundleContext
));
112 if (log
.isTraceEnabled())
113 log
.trace("Registered favicon " + faviconRelPath
);
118 if (!properties
.containsKey(WebClient
.PAGE_TITLE
))
120 WebClient
.PAGE_TITLE
,
121 Character
.toUpperCase(page
.charAt(0))
122 + page
.substring(1));
125 if (!properties
.containsKey(WebClient
.BODY_HTML
))
126 properties
.put(WebClient
.BODY_HTML
, DEFAULT_LOADING_BODY
);
128 application
.addEntryPoint("/" + page
, new CmsEntryPointFactory(
130 log
.info("Registered entry point /" + page
);
134 for (String themeId
: styleSheets
.keySet()) {
135 List
<String
> cssLst
= styleSheets
.get(themeId
);
136 for (String css
: cssLst
) {
137 application
.addStyleSheet(themeId
, css
,
138 new BundleResourceLoader(bundleContext
));
142 } catch (RuntimeException e
) {
143 // Easier access to initialisation errors
144 log
.error("Unexpected exception when configuring RWT application.",
150 public void init() throws RepositoryException
{
151 // if (workspace == null)
152 // throw new CmsException(
153 // "Workspace must be set when calling initialization."
154 // + " Please make sure that read-only and read-write roles"
155 // + " have been properly configured:"
156 // + " the defaults are open.");
158 Session session
= null;
160 session
= JcrUtils
.loginOrCreateWorkspace(repository
, workspace
);
161 VersionManager vm
= session
.getWorkspace().getVersionManager();
162 if (!vm
.isCheckedOut("/"))
164 JcrUtils
.mkdirs(session
, basePath
);
165 for (String principal
: rwPrincipals
)
166 JcrUtils
.addPrivilege(session
, basePath
, principal
,
167 Privilege
.JCR_WRITE
);
168 for (String principal
: roPrincipals
)
169 JcrUtils
.addPrivilege(session
, basePath
, principal
,
172 for (String pageName
: pages
.keySet()) {
174 initPage(session
, pages
.get(pageName
));
176 } catch (Exception e
) {
177 throw new CmsException(
178 "Cannot initialize page " + pageName
, e
);
183 JcrUtils
.logoutQuietly(session
);
187 protected void initPage(Session adminSession
, CmsUiProvider page
)
188 throws RepositoryException
{
189 if (page
instanceof LifeCycleUiProvider
)
190 ((LifeCycleUiProvider
) page
).init(adminSession
);
193 public void destroy() {
194 for (String pageName
: pages
.keySet()) {
196 CmsUiProvider page
= pages
.get(pageName
);
197 if (page
instanceof LifeCycleUiProvider
)
198 ((LifeCycleUiProvider
) page
).destroy();
199 } catch (Exception e
) {
200 log
.error("Cannot destroy page " + pageName
, e
);
205 public void setRepository(Repository repository
) {
206 this.repository
= repository
;
209 public void setWorkspace(String workspace
) {
210 this.workspace
= workspace
;
213 public void setCmsLogin(CmsLogin cmsLogin
) {
214 this.cmsLogin
= cmsLogin
;
217 public void setHeader(CmsUiProvider header
) {
218 this.header
= header
;
221 public void setPages(Map
<String
, CmsUiProvider
> pages
) {
225 public void setBasePath(String basePath
) {
226 this.basePath
= basePath
;
229 public void setRoPrincipals(List
<String
> roPrincipals
) {
230 this.roPrincipals
= roPrincipals
;
233 public void setRwPrincipals(List
<String
> rwPrincipals
) {
234 this.rwPrincipals
= rwPrincipals
;
237 public void setHeaderHeight(Integer headerHeight
) {
238 this.headerHeight
= headerHeight
;
241 // public void setEntryPoints(
242 // Map<String, EntryPointFactory> entryPointFactories) {
243 // this.entryPoints = entryPointFactories;
246 public void setBranding(Map
<String
, Map
<String
, String
>> branding
) {
247 this.branding
= branding
;
250 public void setStyleSheets(Map
<String
, List
<String
>> styleSheets
) {
251 this.styleSheets
= styleSheets
;
254 public void setBundleContext(BundleContext bundleContext
) {
255 this.bundleContext
= bundleContext
;
258 public void setResources(List
<String
> resources
) {
259 this.resources
= resources
;
262 class CmsExceptionHandler
implements ExceptionHandler
{
265 public void handleException(Throwable throwable
) {
266 CmsSession
.current
.get().exception(throwable
);
271 private class CmsEntryPointFactory
implements EntryPointFactory
{
272 private final String page
;
274 public CmsEntryPointFactory(String page
) {
279 public EntryPoint
create() {
280 CmsEntryPoint entryPoint
= new CmsEntryPoint(repository
, workspace
,
282 entryPoint
.setState("");
283 CmsSession
.current
.set(entryPoint
);
289 private class CmsEntryPoint
extends AbstractCmsEntryPoint
{
290 private Composite headerArea
;
291 private Composite bodyArea
;
292 private final CmsUiProvider uiProvider
;
294 public CmsEntryPoint(Repository repository
, String workspace
,
295 CmsUiProvider uiProvider
) {
296 super(repository
, workspace
);
297 this.uiProvider
= uiProvider
;
301 protected void createContents(Composite parent
) {
303 getShell().getDisplay().setData(CmsSession
.KEY
, this);
305 parent
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true,
307 parent
.setLayout(CmsUtils
.noSpaceGridLayout());
309 headerArea
= new Composite(parent
, SWT
.NONE
);
310 headerArea
.setLayout(new FillLayout());
311 GridData headerData
= new GridData(SWT
.FILL
, SWT
.FILL
, false,
313 headerData
.heightHint
= headerHeight
;
314 headerArea
.setLayoutData(headerData
);
317 bodyArea
= new Composite(parent
, SWT
.NONE
);
318 bodyArea
.setData(RWT
.CUSTOM_VARIANT
, CmsStyles
.CMS_BODY
);
319 bodyArea
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true,
321 // Should not be set here: it then prevent all children
322 // composite to define a background color via CSS
323 // bodyArea.setBackgroundMode(SWT.INHERIT_DEFAULT);
324 bodyArea
.setLayout(CmsUtils
.noSpaceGridLayout());
326 } catch (Exception e
) {
327 throw new CmsException("Cannot create entrypoint contents", e
);
332 protected void refreshHeader() {
333 if (headerArea
== null)
335 for (Control child
: headerArea
.getChildren())
338 header
.createUi(headerArea
, getNode());
339 } catch (RepositoryException e
) {
340 throw new CmsException("Cannot refresh header", e
);
342 headerArea
.layout(true, true);
346 protected void refreshBody() {
347 if (bodyArea
== null)
350 for (Control child
: bodyArea
.getChildren())
352 bodyArea
.setLayout(CmsUtils
.noSpaceGridLayout());
355 Throwable exception
= getException();
356 if (exception
!= null) {
357 new Label(bodyArea
, SWT
.NONE
).setText("Unreachable state : "
359 if (getNode() != null)
360 new Label(bodyArea
, SWT
.NONE
).setText("Context : "
363 Text errorText
= new Text(bodyArea
, SWT
.MULTI
| SWT
.H_SCROLL
365 errorText
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true,
367 StringWriter sw
= new StringWriter();
368 exception
.printStackTrace(new PrintWriter(sw
));
369 errorText
.setText(sw
.toString());
370 IOUtils
.closeQuietly(sw
);
374 String state
= getState();
377 throw new CmsException("State cannot be null");
378 uiProvider
.createUi(bodyArea
, getNode());
380 // throw new CmsException("Page cannot be null");
381 // // else if (state.length() == 0)
382 // // log.debug("empty state");
383 // else if (pages.containsKey(page))
384 // pages.get(page).createUi(bodyArea, getNode());
387 // // RWT.getResponse().sendError(404);
388 // // } catch (IOException e) {
389 // // log.error("Cannot send 404 code", e);
391 // throw new CmsException("Unsupported state " + state);
393 } catch (RepositoryException e
) {
394 throw new CmsException("Cannot refresh body", e
);
397 bodyArea
.layout(true, true);
401 protected void logAsAnonymous() {
402 cmsLogin
.logInAsAnonymous();
406 protected Node
getDefaultNode(Session session
)
407 throws RepositoryException
{
408 if (!session
.hasPermission(basePath
, "read")) {
409 if (session
.getUserID().equals("anonymous"))
410 throw new CmsLoginRequiredException();
412 throw new CmsException("Unauthorized");
414 return session
.getNode(basePath
);
418 public CmsImageManager
getImageManager() {
424 private static ResourceLoader
createResourceLoader(final String resourceName
) {
425 return new ResourceLoader() {
426 public InputStream
getResourceAsStream(String resourceName
)
428 return getClass().getClassLoader().getResourceAsStream(
437 private static String DEFAULT_LOADING_BODY
= "<div"
438 + " style=\"position: absolute; left: 50%; top: 50%; margin: -32px -32px; width: 64px; height:64px\">"
439 + "<img src=\"./rwt-resources/icons/loading.gif\" width=\"32\" height=\"32\" style=\"margin: 16px 16px\"/>"