import java.io.IOException;
import java.io.InputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.security.Privilege;
+import javax.jcr.version.VersionManager;
+
+import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.argeo.cms.internal.ImageManagerImpl;
+import org.argeo.cms.util.CmsUtils;
+import org.argeo.jcr.JcrUtils;
import org.eclipse.gemini.blueprint.context.BundleContextAware;
+import org.eclipse.rap.rwt.RWT;
import org.eclipse.rap.rwt.application.Application;
import org.eclipse.rap.rwt.application.Application.OperationMode;
import org.eclipse.rap.rwt.application.ApplicationConfiguration;
+import org.eclipse.rap.rwt.application.EntryPoint;
import org.eclipse.rap.rwt.application.EntryPointFactory;
import org.eclipse.rap.rwt.application.ExceptionHandler;
import org.eclipse.rap.rwt.client.WebClient;
import org.eclipse.rap.rwt.service.ResourceLoader;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
import org.osgi.framework.BundleContext;
/** Configures an Argeo CMS RWT application. */
BundleContextAware {
final static Log log = LogFactory.getLog(CmsApplication.class);
- private Map<String, EntryPointFactory> entryPoints = new HashMap<String, EntryPointFactory>();
- private Map<String, Map<String, String>> entryPointsBranding = new HashMap<String, Map<String, String>>();
+ // private Map<String, EntryPointFactory> entryPoints = new HashMap<String,
+ // EntryPointFactory>();
+ private Map<String, Map<String, String>> branding = new HashMap<String, Map<String, String>>();
private Map<String, List<String>> styleSheets = new HashMap<String, List<String>>();
private List<String> resources = new ArrayList<String>();
// private Bundle clientScriptingBundle;
private BundleContext bundleContext;
+ private Repository repository;
+ private String workspace = null;
+ private String basePath = "/";
+ private List<String> roPrincipals = Arrays.asList("anonymous", "everyone");
+ private List<String> rwPrincipals = Arrays.asList("everyone");
+
+ private CmsLogin cmsLogin;
+
+ private CmsUiProvider header;
+ private Map<String, CmsUiProvider> pages = new LinkedHashMap<String, CmsUiProvider>();
+
+ private Integer headerHeight = 40;
+
+ // Managers
+ private CmsImageManager imageManager = new ImageManagerImpl();
+
public void configure(Application application) {
try {
application.setOperationMode(OperationMode.SWT_COMPATIBILITY);
log.debug("Registered resource " + resource);
}
+ Map<String, String> defaultBranding = null;
+ if (branding.containsKey("*"))
+ defaultBranding = branding.get("*");
+
// entry points
- for (String entryPoint : entryPoints.keySet()) {
- Map<String, String> properties = new HashMap<String, String>();
- if (entryPointsBranding.containsKey(entryPoint)) {
- properties = entryPointsBranding.get(entryPoint);
- if (properties.containsKey(WebClient.FAVICON)) {
- String faviconRelPath = properties
- .get(WebClient.FAVICON);
- application.addResource(faviconRelPath,
- new BundleResourceLoader(bundleContext));
- if (log.isTraceEnabled())
- log.trace("Registered favicon " + faviconRelPath);
-
- }
-
- if (!properties.containsKey(WebClient.BODY_HTML))
- properties.put(WebClient.BODY_HTML,
- DEFAULT_LOADING_BODY);
+ for (String page : pages.keySet()) {
+ Map<String, String> properties = defaultBranding != null ? new HashMap<String, String>(
+ defaultBranding) : new HashMap<String, String>();
+ if (branding.containsKey(page)) {
+ properties.putAll(branding.get(page));
+ }
+ // favicon
+ if (properties.containsKey(WebClient.FAVICON)) {
+ String faviconRelPath = properties.get(WebClient.FAVICON);
+ application.addResource(faviconRelPath,
+ new BundleResourceLoader(bundleContext));
+ if (log.isTraceEnabled())
+ log.trace("Registered favicon " + faviconRelPath);
+
}
- application.addEntryPoint("/" + entryPoint,
- entryPoints.get(entryPoint), properties);
- log.info("Registered entry point /" + entryPoint);
+ // page title
+ if (!properties.containsKey(WebClient.PAGE_TITLE))
+ properties.put(
+ WebClient.PAGE_TITLE,
+ Character.toUpperCase(page.charAt(0))
+ + page.substring(1));
+
+ // default body HTML
+ if (!properties.containsKey(WebClient.BODY_HTML))
+ properties.put(WebClient.BODY_HTML, DEFAULT_LOADING_BODY);
+
+ application.addEntryPoint("/" + page, new CmsEntryPointFactory(
+ page), properties);
+ log.info("Registered entry point /" + page);
}
// stylesheets
}
}
-
-// application.addPhaseListener(new CmsPhaseListener());
-
} catch (RuntimeException e) {
// Easier access to initialisation errors
log.error("Unexpected exception when configuring RWT application.",
}
}
- private static ResourceLoader createResourceLoader(final String resourceName) {
- return new ResourceLoader() {
- public InputStream getResourceAsStream(String resourceName)
- throws IOException {
- return getClass().getClassLoader().getResourceAsStream(
- resourceName);
+ public void init() throws RepositoryException {
+ if (workspace == null)
+ throw new CmsException(
+ "Workspace must be set when calling initialization."
+ + " Please make sure that read-only and read-write roles"
+ + " have been properly configured:"
+ + " the defaults are open.");
+
+ Session session = null;
+ try {
+ session = JcrUtils.loginOrCreateWorkspace(repository, workspace);
+ VersionManager vm = session.getWorkspace().getVersionManager();
+ if (!vm.isCheckedOut("/"))
+ vm.checkout("/");
+ JcrUtils.mkdirs(session, basePath);
+ for (String principal : rwPrincipals)
+ JcrUtils.addPrivilege(session, basePath, principal,
+ Privilege.JCR_WRITE);
+ for (String principal : roPrincipals)
+ JcrUtils.addPrivilege(session, basePath, principal,
+ Privilege.JCR_READ);
+
+ for (String pageName : pages.keySet()) {
+ try {
+ initPage(session, pages.get(pageName));
+ session.save();
+ } catch (Exception e) {
+ throw new CmsException(
+ "Cannot initialize page " + pageName, e);
+ }
}
- };
+
+ } finally {
+ JcrUtils.logoutQuietly(session);
+ }
}
- public void setEntryPoints(
- Map<String, EntryPointFactory> entryPointFactories) {
- this.entryPoints = entryPointFactories;
+ protected void initPage(Session adminSession, CmsUiProvider page)
+ throws RepositoryException {
+ if (page instanceof LifeCycleUiProvider)
+ ((LifeCycleUiProvider) page).init(adminSession);
}
- public void setEntryPointsBranding(
- Map<String, Map<String, String>> entryPointBranding) {
- this.entryPointsBranding = entryPointBranding;
+ public void destroy() {
+ for (String pageName : pages.keySet()) {
+ try {
+ CmsUiProvider page = pages.get(pageName);
+ if (page instanceof LifeCycleUiProvider)
+ ((LifeCycleUiProvider) page).destroy();
+ } catch (Exception e) {
+ log.error("Cannot destroy page " + pageName, e);
+ }
+ }
+ }
+
+ public void setRepository(Repository repository) {
+ this.repository = repository;
+ }
+
+ public void setWorkspace(String workspace) {
+ this.workspace = workspace;
+ }
+
+ public void setCmsLogin(CmsLogin cmsLogin) {
+ this.cmsLogin = cmsLogin;
+ }
+
+ public void setHeader(CmsUiProvider header) {
+ this.header = header;
+ }
+
+ public void setPages(Map<String, CmsUiProvider> pages) {
+ this.pages = pages;
+ }
+
+ public void setBasePath(String basePath) {
+ this.basePath = basePath;
+ }
+
+ public void setRoPrincipals(List<String> roPrincipals) {
+ this.roPrincipals = roPrincipals;
+ }
+
+ public void setRwPrincipals(List<String> rwPrincipals) {
+ this.rwPrincipals = rwPrincipals;
+ }
+
+ public void setHeaderHeight(Integer headerHeight) {
+ this.headerHeight = headerHeight;
+ }
+
+ // public void setEntryPoints(
+ // Map<String, EntryPointFactory> entryPointFactories) {
+ // this.entryPoints = entryPointFactories;
+ // }
+
+ public void setBranding(Map<String, Map<String, String>> branding) {
+ this.branding = branding;
}
public void setStyleSheets(Map<String, List<String>> styleSheets) {
}
-// class CmsPhaseListener implements PhaseListener {
-// private static final long serialVersionUID = -1966645586738534609L;
-//
-// @Override
-// public PhaseId getPhaseId() {
-// return PhaseId.RENDER;
-// }
-//
-// @Override
-// public void beforePhase(PhaseEvent event) {
-// CmsSession cmsSession = CmsSession.current.get();
-// String state = cmsSession.getState();
-// if (state == null)
-// cmsSession.navigateTo("~");
-// }
-//
-// @Override
-// public void afterPhase(PhaseEvent event) {
-// }
-// }
+ private class CmsEntryPointFactory implements EntryPointFactory {
+ private final String page;
+
+ public CmsEntryPointFactory(String page) {
+ this.page = page;
+ }
+
+ @Override
+ public EntryPoint create() {
+ CmsEntryPoint entryPoint = new CmsEntryPoint(repository, workspace,
+ pages.get(page));
+ entryPoint.setState("");
+ CmsSession.current.set(entryPoint);
+ return entryPoint;
+ }
+
+ }
+
+ private class CmsEntryPoint extends AbstractCmsEntryPoint {
+ private Composite headerArea;
+ private Composite bodyArea;
+ private final CmsUiProvider uiProvider;
+
+ public CmsEntryPoint(Repository repository, String workspace,
+ CmsUiProvider uiProvider) {
+ super(repository, workspace);
+ this.uiProvider = uiProvider;
+ }
+
+ @Override
+ protected void createContents(Composite parent) {
+ try {
+ getShell().getDisplay().setData(CmsSession.KEY, this);
+
+ parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
+ true));
+ parent.setLayout(CmsUtils.noSpaceGridLayout());
+
+ headerArea = new Composite(parent, SWT.NONE);
+ headerArea.setLayout(new FillLayout());
+ GridData headerData = new GridData(SWT.FILL, SWT.FILL, false,
+ false);
+ headerData.heightHint = headerHeight;
+ headerArea.setLayoutData(headerData);
+ refreshHeader();
+
+ bodyArea = new Composite(parent, SWT.NONE);
+ bodyArea.setData(RWT.CUSTOM_VARIANT, CmsStyles.CMS_BODY);
+ bodyArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
+ true));
+ bodyArea.setBackgroundMode(SWT.INHERIT_DEFAULT);
+ bodyArea.setLayout(CmsUtils.noSpaceGridLayout());
+ refreshBody();
+ } catch (Exception e) {
+ throw new CmsException("Cannot create entrypoint contents", e);
+ }
+ }
+
+ @Override
+ protected void refreshHeader() {
+ if (headerArea == null)
+ return;
+ for (Control child : headerArea.getChildren())
+ child.dispose();
+ try {
+ header.createUi(headerArea, getNode());
+ } catch (RepositoryException e) {
+ throw new CmsException("Cannot refresh header", e);
+ }
+ headerArea.layout(true, true);
+ }
+
+ @Override
+ protected void refreshBody() {
+ if (bodyArea == null)
+ return;
+ // clear
+ for (Control child : bodyArea.getChildren())
+ child.dispose();
+ bodyArea.setLayout(CmsUtils.noSpaceGridLayout());
+
+ // Exception
+ Throwable exception = getException();
+ if (exception != null) {
+ new Label(bodyArea, SWT.NONE).setText("Unreachable state : "
+ + getState());
+ if (getNode() != null)
+ new Label(bodyArea, SWT.NONE).setText("Context : "
+ + getNode());
+
+ Text errorText = new Text(bodyArea, SWT.MULTI | SWT.H_SCROLL
+ | SWT.V_SCROLL);
+ errorText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
+ true));
+ StringWriter sw = new StringWriter();
+ exception.printStackTrace(new PrintWriter(sw));
+ errorText.setText(sw.toString());
+ IOUtils.closeQuietly(sw);
+ resetException();
+ // TODO report
+ } else {
+ String state = getState();
+ try {
+ if (state == null)
+ throw new CmsException("State cannot be null");
+ uiProvider.createUi(bodyArea, getNode());
+ // if (page == null)
+ // throw new CmsException("Page cannot be null");
+ // // else if (state.length() == 0)
+ // // log.debug("empty state");
+ // else if (pages.containsKey(page))
+ // pages.get(page).createUi(bodyArea, getNode());
+ // else {
+ // // try {
+ // // RWT.getResponse().sendError(404);
+ // // } catch (IOException e) {
+ // // log.error("Cannot send 404 code", e);
+ // // }
+ // throw new CmsException("Unsupported state " + state);
+ // }
+ } catch (RepositoryException e) {
+ throw new CmsException("Cannot refresh body", e);
+ }
+ }
+ bodyArea.layout(true, true);
+ }
+
+ @Override
+ protected void logAsAnonymous() {
+ cmsLogin.logInAsAnonymous();
+ }
+
+ @Override
+ protected Node getDefaultNode(Session session)
+ throws RepositoryException {
+ if (!session.hasPermission(basePath, "read")) {
+ if (session.getUserID().equals("anonymous"))
+ throw new CmsLoginRequiredException();
+ else
+ throw new CmsException("Unauthorized");
+ }
+ return session.getNode(basePath);
+ }
+
+ @Override
+ public CmsImageManager getImageManager() {
+ return imageManager;
+ }
+
+ }
+
+ private static ResourceLoader createResourceLoader(final String resourceName) {
+ return new ResourceLoader() {
+ public InputStream getResourceAsStream(String resourceName)
+ throws IOException {
+ return getClass().getClassLoader().getResourceAsStream(
+ resourceName);
+ }
+ };
+ }
/*
* TEXTS