From: Bruno Sinou Date: Thu, 15 Sep 2016 11:45:36 +0000 (+0000) Subject: Move UI classes to cms.ui X-Git-Tag: argeo-commons-2.1.46~21 X-Git-Url: http://git.argeo.org/?a=commitdiff_plain;h=c5fa035468228d1f87ab5431a3fad17403eee1c3;p=lgpl%2Fargeo-commons.git Move UI classes to cms.ui git-svn-id: https://svn.argeo.org/commons/trunk@9159 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- diff --git a/org.argeo.cms.ui/src/org/argeo/cms/forms/FormEditorHeader.java b/org.argeo.cms.ui/src/org/argeo/cms/forms/FormEditorHeader.java index c12e2f000..92ce9da0c 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/forms/FormEditorHeader.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/forms/FormEditorHeader.java @@ -5,7 +5,7 @@ import java.util.Observer; import javax.jcr.Node; -import org.argeo.cms.CmsEditable; +import org.argeo.cms.ui.CmsEditable; import org.argeo.cms.util.CmsUtils; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionEvent; diff --git a/org.argeo.cms.ui/src/org/argeo/cms/forms/FormPageViewer.java b/org.argeo.cms.ui/src/org/argeo/cms/forms/FormPageViewer.java index 8526fcaca..afc7cb15b 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/forms/FormPageViewer.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/forms/FormPageViewer.java @@ -16,11 +16,11 @@ import javax.jcr.ValueFormatException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.argeo.cms.CmsEditable; import org.argeo.cms.CmsException; -import org.argeo.cms.CmsImageManager; import org.argeo.cms.CmsNames; import org.argeo.cms.text.Img; +import org.argeo.cms.ui.CmsEditable; +import org.argeo.cms.ui.CmsImageManager; import org.argeo.cms.ui.internal.text.MarkupValidatorCopy; import org.argeo.cms.util.CmsUtils; import org.argeo.cms.viewers.AbstractPageViewer; diff --git a/org.argeo.cms.ui/src/org/argeo/cms/forms/FormUtils.java b/org.argeo.cms.ui/src/org/argeo/cms/forms/FormUtils.java index f8d08b08d..d0fa9269c 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/forms/FormUtils.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/forms/FormUtils.java @@ -12,7 +12,7 @@ import javax.jcr.RepositoryException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.cms.CmsException; -import org.argeo.cms.CmsView; +import org.argeo.cms.ui.CmsView; import org.argeo.cms.util.CmsUtils; import org.argeo.eclipse.ui.EclipseUiUtils; import org.eclipse.jface.fieldassist.ControlDecoration; diff --git a/org.argeo.cms.ui/src/org/argeo/cms/maintenance/Browse.java b/org.argeo.cms.ui/src/org/argeo/cms/maintenance/Browse.java index 7dafd72c4..0389205ca 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/maintenance/Browse.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/maintenance/Browse.java @@ -18,8 +18,8 @@ import javax.jcr.Value; import org.argeo.cms.CmsException; import org.argeo.cms.CmsTypes; -import org.argeo.cms.CmsUiProvider; import org.argeo.cms.text.Img; +import org.argeo.cms.ui.CmsUiProvider; import org.argeo.cms.util.CmsLink; import org.argeo.cms.util.CmsUtils; import org.argeo.cms.widgets.EditableImage; diff --git a/org.argeo.cms.ui/src/org/argeo/cms/maintenance/NonAdminPage.java b/org.argeo.cms.ui/src/org/argeo/cms/maintenance/NonAdminPage.java index b27d50659..8a903448f 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/maintenance/NonAdminPage.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/maintenance/NonAdminPage.java @@ -3,7 +3,7 @@ package org.argeo.cms.maintenance; import javax.jcr.Node; import javax.jcr.RepositoryException; -import org.argeo.cms.CmsUiProvider; +import org.argeo.cms.ui.CmsUiProvider; import org.argeo.cms.util.CmsUtils; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; diff --git a/org.argeo.cms.ui/src/org/argeo/cms/text/CustomTextEditor.java b/org.argeo.cms.ui/src/org/argeo/cms/text/CustomTextEditor.java index c7491e02c..442ad7815 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/text/CustomTextEditor.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/text/CustomTextEditor.java @@ -5,7 +5,7 @@ import static org.argeo.cms.util.CmsUtils.fillWidth; import javax.jcr.Node; import javax.jcr.RepositoryException; -import org.argeo.cms.CmsEditable; +import org.argeo.cms.ui.CmsEditable; import org.argeo.cms.ui.internal.text.AbstractTextViewer; import org.argeo.cms.viewers.Section; import org.eclipse.swt.widgets.Composite; diff --git a/org.argeo.cms.ui/src/org/argeo/cms/text/Img.java b/org.argeo.cms.ui/src/org/argeo/cms/text/Img.java index e0cf21624..12f65f35e 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/text/Img.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/text/Img.java @@ -4,7 +4,7 @@ import javax.jcr.Node; import javax.jcr.RepositoryException; import org.argeo.cms.CmsException; -import org.argeo.cms.CmsImageManager; +import org.argeo.cms.ui.CmsImageManager; import org.argeo.cms.ui.internal.JcrFileUploadReceiver; import org.argeo.cms.util.CmsUtils; import org.argeo.cms.viewers.NodePart; diff --git a/org.argeo.cms.ui/src/org/argeo/cms/text/StandardTextEditor.java b/org.argeo.cms.ui/src/org/argeo/cms/text/StandardTextEditor.java index 3d1dc3f6f..f39317ac2 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/text/StandardTextEditor.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/text/StandardTextEditor.java @@ -6,8 +6,8 @@ import javax.jcr.Node; import javax.jcr.Property; import javax.jcr.RepositoryException; -import org.argeo.cms.CmsEditable; import org.argeo.cms.CmsTypes; +import org.argeo.cms.ui.CmsEditable; import org.argeo.cms.ui.internal.text.AbstractTextViewer; import org.argeo.cms.util.CmsUtils; import org.argeo.cms.viewers.Section; diff --git a/org.argeo.cms.ui/src/org/argeo/cms/text/TextEditorHeader.java b/org.argeo.cms.ui/src/org/argeo/cms/text/TextEditorHeader.java index e70a4d06e..5ae053683 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/text/TextEditorHeader.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/text/TextEditorHeader.java @@ -3,7 +3,7 @@ package org.argeo.cms.text; import java.util.Observable; import java.util.Observer; -import org.argeo.cms.CmsEditable; +import org.argeo.cms.ui.CmsEditable; import org.argeo.cms.util.CmsUtils; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionEvent; diff --git a/org.argeo.cms.ui/src/org/argeo/cms/text/WikiPage.java b/org.argeo.cms.ui/src/org/argeo/cms/text/WikiPage.java index 38af381a5..a01cc3551 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/text/WikiPage.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/text/WikiPage.java @@ -6,10 +6,10 @@ import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.nodetype.NodeType; -import org.argeo.cms.CmsEditable; import org.argeo.cms.CmsNames; import org.argeo.cms.CmsTypes; -import org.argeo.cms.CmsUiProvider; +import org.argeo.cms.ui.CmsEditable; +import org.argeo.cms.ui.CmsUiProvider; import org.argeo.cms.util.CmsLink; import org.argeo.cms.util.CmsUtils; import org.argeo.cms.viewers.JcrVersionCmsEditable; diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/AbstractCmsEntryPoint.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/AbstractCmsEntryPoint.java new file mode 100644 index 000000000..4729c5b75 --- /dev/null +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/AbstractCmsEntryPoint.java @@ -0,0 +1,334 @@ +package org.argeo.cms.ui; + +import java.security.PrivilegedAction; +import java.util.HashMap; +import java.util.Map; + +import javax.jcr.Node; +import javax.jcr.PathNotFoundException; +import javax.jcr.Property; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.nodetype.NodeType; +import javax.security.auth.Subject; +import javax.security.auth.login.CredentialNotFoundException; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.cms.CmsException; +import org.argeo.cms.auth.AuthConstants; +import org.argeo.cms.auth.HttpRequestCallbackHandler; +import org.argeo.eclipse.ui.specific.UiContext; +import org.argeo.jcr.JcrUtils; +import org.argeo.node.NodeAuthenticated; +import org.eclipse.rap.rwt.RWT; +import org.eclipse.rap.rwt.application.AbstractEntryPoint; +import org.eclipse.rap.rwt.client.WebClient; +import org.eclipse.rap.rwt.client.service.BrowserNavigation; +import org.eclipse.rap.rwt.client.service.BrowserNavigationEvent; +import org.eclipse.rap.rwt.client.service.BrowserNavigationListener; +import org.eclipse.rap.rwt.client.service.JavaScriptExecutor; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** Manages history and navigation */ +public abstract class AbstractCmsEntryPoint extends AbstractEntryPoint implements CmsView { + private final Log log = LogFactory.getLog(AbstractCmsEntryPoint.class); + + private final Subject subject; + private LoginContext loginContext; + + private final Repository repository; + private final String workspace; + private final String defaultPath; + private final Map factoryProperties; + + // Current state + private Session session; + private Node node; + private String nodePath;// useful when changing auth + private String state; + private String page; + private Throwable exception; + + // Client services + private final JavaScriptExecutor jsExecutor; + private final BrowserNavigation browserNavigation; + + public AbstractCmsEntryPoint(Repository repository, String workspace, String defaultPath, + Map factoryProperties) { + this.repository = repository; + this.workspace = workspace; + this.defaultPath = defaultPath; + this.factoryProperties = new HashMap(factoryProperties); + subject = new Subject(); + + // Initial login + try { + loginContext = new LoginContext(AuthConstants.LOGIN_CONTEXT_USER, subject, + new HttpRequestCallbackHandler(UiContext.getHttpRequest())); + loginContext.login(); + } catch (CredentialNotFoundException e) { + try { + loginContext = new LoginContext(AuthConstants.LOGIN_CONTEXT_ANONYMOUS, subject); + loginContext.login(); + } catch (LoginException e1) { + throw new CmsException("Cannot log as anonymous", e); + } + } catch (LoginException e) { + throw new CmsException("Cannot initialize subject", e); + } + authChange(loginContext); + + jsExecutor = RWT.getClient().getService(JavaScriptExecutor.class); + browserNavigation = RWT.getClient().getService(BrowserNavigation.class); + if (browserNavigation != null) + browserNavigation.addBrowserNavigationListener(new CmsNavigationListener()); + } + + @Override + protected Shell createShell(Display display) { + Shell shell = super.createShell(display); + shell.setData(RWT.CUSTOM_VARIANT, CmsStyles.CMS_SHELL); + display.disposeExec(new Runnable() { + + @Override + public void run() { + if (log.isTraceEnabled()) + log.trace("Logging out " + session); + JcrUtils.logoutQuietly(session); + } + }); + return shell; + } + + @Override + protected final void createContents(final Composite parent) { + UiContext.setData(NodeAuthenticated.KEY, this); + Subject.doAs(subject, new PrivilegedAction() { + @Override + public Void run() { + try { + initUi(parent); + } catch (Exception e) { + throw new CmsException("Cannot create entrypoint contents", e); + } + return null; + } + }); + } + + /** Create UI */ + protected abstract void initUi(Composite parent); + + /** Recreate UI after navigation or auth change */ + protected abstract void refresh(); + + /** + * The node to return when no node was found (for authenticated users and + * anonymous) + */ + protected Node getDefaultNode(Session session) throws RepositoryException { + if (!session.hasPermission(defaultPath, "read")) { + if (session.getUserID().equals(AuthConstants.ROLE_ANONYMOUS)) + // TODO throw a special exception + throw new CmsException("Login required"); + else + throw new CmsException("Unauthorized"); + } + return session.getNode(defaultPath); + } + + protected String getBaseTitle() { + return factoryProperties.get(WebClient.PAGE_TITLE); + } + + public void navigateTo(String state) { + exception = null; + String title = setState(state); + doRefresh(); + if (browserNavigation != null) + browserNavigation.pushState(state, title); + } + + @Override + public synchronized Subject getSubject() { + return subject; + } + + @Override + public synchronized void logout() { + if (loginContext == null) + throw new CmsException("Login context should not be null"); + try { + loginContext.logout(); + LoginContext anonymousLc = new LoginContext(AuthConstants.LOGIN_CONTEXT_ANONYMOUS, subject); + anonymousLc.login(); + authChange(anonymousLc); + } catch (LoginException e) { + throw new CmsException("Cannot logout", e); + } + } + + @Override + public synchronized void authChange(LoginContext loginContext) { + if (loginContext == null) + throw new CmsException("Login context cannot be null"); + this.loginContext = loginContext; + Subject.doAs(loginContext.getSubject(), new PrivilegedAction() { + + @Override + public Void run() { + try { + JcrUtils.logoutQuietly(session); + session = repository.login(workspace); + if (nodePath != null) + try { + node = session.getNode(nodePath); + } catch (PathNotFoundException e) { + // logout(); + // session = repository.login(workspace); + navigateTo("~"); + // throw e; + } + + // refresh UI + doRefresh(); + } catch (RepositoryException e) { + throw new CmsException("Cannot perform auth change", e); + } + return null; + } + + }); + + } + + @Override + public void exception(final Throwable e) { + AbstractCmsEntryPoint.this.exception = e; + log.error("Unexpected exception in CMS", e); + doRefresh(); + } + + protected synchronized void doRefresh() { + Subject.doAs(subject, new PrivilegedAction() { + @Override + public Void run() { + refresh(); + return null; + } + }); + } + + /** Sets the state of the entry point and retrieve the related JCR node. */ + protected synchronized String setState(String newState) { + String previousState = this.state; + + Node node = null; + page = null; + this.state = newState; + if (newState.equals("~")) + this.state = ""; + + try { + int firstSlash = state.indexOf('/'); + if (firstSlash == 0) { + if (session.nodeExists(state)) + node = session.getNode(state); + else + throw new CmsException("Data " + state + " does not exist"); + page = ""; + } else if (firstSlash > 0) { + String prefix = state.substring(0, firstSlash); + String path = state.substring(firstSlash); + if (session.nodeExists(path)) + node = session.getNode(path); + else + throw new CmsException("Data " + path + " does not exist"); + page = prefix; + } else { + node = getDefaultNode(session); + page = state; + } + setNode(node); + String title = publishMetaData(node); + + if (log.isTraceEnabled()) + log.trace("node=" + node + ", state=" + state + " (page=" + page + ")"); + + return title; + } catch (Exception e) { + log.error("Cannot set state '" + state + "'", e); + if (previousState.equals("")) + previousState = "~"; + navigateTo(previousState); + throw new CmsException("Unexpected issue when accessing #" + newState, e); + } + } + + private String publishMetaData(Node node) throws RepositoryException { + // Title + String title; + if (node.isNodeType(NodeType.MIX_TITLE) && node.hasProperty(Property.JCR_TITLE)) + title = node.getProperty(Property.JCR_TITLE).getString() + " - " + getBaseTitle(); + else + title = getBaseTitle(); + + HttpServletRequest request = UiContext.getHttpRequest(); + if (request == null) + return null; + + StringBuilder js = new StringBuilder(); + title = title.replace("'", "\\'");// sanitize + js.append("document.title = '" + title + "';"); + jsExecutor.execute(js.toString()); + return title; + } + + // Simply remove some illegal character + // private String clean(String stringToClean) { + // return stringToClean.replaceAll("'", "").replaceAll("\\n", "") + // .replaceAll("\\t", ""); + // } + + protected synchronized Node getNode() { + return node; + } + + private synchronized void setNode(Node node) throws RepositoryException { + this.node = node; + this.nodePath = node == null ? null : node.getPath(); + } + + protected String getState() { + return state; + } + + protected Throwable getException() { + return exception; + } + + protected void resetException() { + exception = null; + } + + protected Session getSession() { + return session; + } + + private class CmsNavigationListener implements BrowserNavigationListener { + private static final long serialVersionUID = -3591018803430389270L; + + @Override + public void navigated(BrowserNavigationEvent event) { + setState(event.getState()); + refresh(); + } + } +} \ No newline at end of file diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsConstants.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsConstants.java new file mode 100644 index 000000000..dcbc02487 --- /dev/null +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsConstants.java @@ -0,0 +1,22 @@ +package org.argeo.cms.ui; + +import org.eclipse.rap.rwt.RWT; +import org.eclipse.swt.graphics.Point; + +/** Commons constants */ +public interface CmsConstants { + // DATAKEYS + public final static String STYLE = RWT.CUSTOM_VARIANT; + public final static String MARKUP = RWT.MARKUP_ENABLED; + public final static String ITEM_HEIGHT = RWT.CUSTOM_ITEM_HEIGHT; + + // EVENT DETAILS + public final static int HYPERLINK = RWT.HYPERLINK; + + // STANDARD RESOURCES + public final static String LOADING_IMAGE = "icons/loading.gif"; + + public final static String NO_IMAGE = "icons/noPic-square-640px.png"; + public final static Point NO_IMAGE_SIZE = new Point(640, 640); + public final static Float NO_IMAGE_RATIO = 1f; +} diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsEditable.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsEditable.java new file mode 100644 index 000000000..687e3e83b --- /dev/null +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsEditable.java @@ -0,0 +1,36 @@ +package org.argeo.cms.ui; + +/** API NOT STABLE (yet). */ +public interface CmsEditable { + + /** Whether the calling thread can edit, the value is immutable */ + public Boolean canEdit(); + + public Boolean isEditing(); + + public void startEditing(); + + public void stopEditing(); + + public static CmsEditable NON_EDITABLE = new CmsEditable() { + + @Override + public void stopEditing() { + } + + @Override + public void startEditing() { + } + + @Override + public Boolean isEditing() { + return false; + } + + @Override + public Boolean canEdit() { + return false; + } + }; + +} diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsEditionEvent.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsEditionEvent.java new file mode 100644 index 000000000..872142bca --- /dev/null +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsEditionEvent.java @@ -0,0 +1,23 @@ +package org.argeo.cms.ui; + +import java.util.EventObject; + +/** Notify of the edition lifecycle */ +public class CmsEditionEvent extends EventObject { + private static final long serialVersionUID = 950914736016693110L; + + public final static Integer START_EDITING = 0; + public final static Integer STOP_EDITING = 1; + + private final Integer type; + + public CmsEditionEvent(Object source, Integer type) { + super(source); + this.type = type; + } + + public Integer getType() { + return type; + } + +} diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsImageManager.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsImageManager.java new file mode 100644 index 000000000..ddae6006e --- /dev/null +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsImageManager.java @@ -0,0 +1,48 @@ +package org.argeo.cms.ui; + +import java.io.InputStream; + +import javax.jcr.Binary; +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Control; + +/** Read and write access to images. */ +public interface CmsImageManager { + /** Load image in control */ + public Boolean load(Node node, Control control, Point size) + throws RepositoryException; + + /** @return (0,0) if not available */ + public Point getImageSize(Node node) throws RepositoryException; + + /** + * The related factoryProperties; - - // Current state - private Session session; - private Node node; - private String nodePath;// useful when changing auth - private String state; - private String page; - private Throwable exception; - - // Client services - private final JavaScriptExecutor jsExecutor; - private final BrowserNavigation browserNavigation; - - public AbstractCmsEntryPoint(Repository repository, String workspace, String defaultPath, - Map factoryProperties) { - this.repository = repository; - this.workspace = workspace; - this.defaultPath = defaultPath; - this.factoryProperties = new HashMap(factoryProperties); - subject = new Subject(); - - // Initial login - try { - loginContext = new LoginContext(AuthConstants.LOGIN_CONTEXT_USER, subject, - new HttpRequestCallbackHandler(UiContext.getHttpRequest())); - loginContext.login(); - } catch (CredentialNotFoundException e) { - try { - loginContext = new LoginContext(AuthConstants.LOGIN_CONTEXT_ANONYMOUS, subject); - loginContext.login(); - } catch (LoginException e1) { - throw new CmsException("Cannot log as anonymous", e); - } - } catch (LoginException e) { - throw new CmsException("Cannot initialize subject", e); - } - authChange(loginContext); - - jsExecutor = RWT.getClient().getService(JavaScriptExecutor.class); - browserNavigation = RWT.getClient().getService(BrowserNavigation.class); - if (browserNavigation != null) - browserNavigation.addBrowserNavigationListener(new CmsNavigationListener()); - } - - @Override - protected Shell createShell(Display display) { - Shell shell = super.createShell(display); - shell.setData(RWT.CUSTOM_VARIANT, CmsStyles.CMS_SHELL); - display.disposeExec(new Runnable() { - - @Override - public void run() { - if (log.isTraceEnabled()) - log.trace("Logging out " + session); - JcrUtils.logoutQuietly(session); - } - }); - return shell; - } - - @Override - protected final void createContents(final Composite parent) { - UiContext.setData(NodeAuthenticated.KEY, this); - Subject.doAs(subject, new PrivilegedAction() { - @Override - public Void run() { - try { - initUi(parent); - } catch (Exception e) { - throw new CmsException("Cannot create entrypoint contents", e); - } - return null; - } - }); - } - - /** Create UI */ - protected abstract void initUi(Composite parent); - - /** Recreate UI after navigation or auth change */ - protected abstract void refresh(); - - /** - * The node to return when no node was found (for authenticated users and - * anonymous) - */ - protected Node getDefaultNode(Session session) throws RepositoryException { - if (!session.hasPermission(defaultPath, "read")) { - if (session.getUserID().equals(AuthConstants.ROLE_ANONYMOUS)) - // TODO throw a special exception - throw new CmsException("Login required"); - else - throw new CmsException("Unauthorized"); - } - return session.getNode(defaultPath); - } - - protected String getBaseTitle() { - return factoryProperties.get(WebClient.PAGE_TITLE); - } - - public void navigateTo(String state) { - exception = null; - String title = setState(state); - doRefresh(); - if (browserNavigation != null) - browserNavigation.pushState(state, title); - } - - @Override - public synchronized Subject getSubject() { - return subject; - } - - @Override - public synchronized void logout() { - if (loginContext == null) - throw new CmsException("Login context should not be null"); - try { - loginContext.logout(); - LoginContext anonymousLc = new LoginContext(AuthConstants.LOGIN_CONTEXT_ANONYMOUS, subject); - anonymousLc.login(); - authChange(anonymousLc); - } catch (LoginException e) { - throw new CmsException("Cannot logout", e); - } - } - - @Override - public synchronized void authChange(LoginContext loginContext) { - if (loginContext == null) - throw new CmsException("Login context cannot be null"); - this.loginContext = loginContext; - Subject.doAs(loginContext.getSubject(), new PrivilegedAction() { - - @Override - public Void run() { - try { - JcrUtils.logoutQuietly(session); - session = repository.login(workspace); - if (nodePath != null) - try { - node = session.getNode(nodePath); - } catch (PathNotFoundException e) { - // logout(); - // session = repository.login(workspace); - navigateTo("~"); - // throw e; - } - - // refresh UI - doRefresh(); - } catch (RepositoryException e) { - throw new CmsException("Cannot perform auth change", e); - } - return null; - } - - }); - - } - - @Override - public void exception(final Throwable e) { - AbstractCmsEntryPoint.this.exception = e; - log.error("Unexpected exception in CMS", e); - doRefresh(); - } - - protected synchronized void doRefresh() { - Subject.doAs(subject, new PrivilegedAction() { - @Override - public Void run() { - refresh(); - return null; - } - }); - } - - /** Sets the state of the entry point and retrieve the related JCR node. */ - protected synchronized String setState(String newState) { - String previousState = this.state; - - Node node = null; - page = null; - this.state = newState; - if (newState.equals("~")) - this.state = ""; - - try { - int firstSlash = state.indexOf('/'); - if (firstSlash == 0) { - if (session.nodeExists(state)) - node = session.getNode(state); - else - throw new CmsException("Data " + state + " does not exist"); - page = ""; - } else if (firstSlash > 0) { - String prefix = state.substring(0, firstSlash); - String path = state.substring(firstSlash); - if (session.nodeExists(path)) - node = session.getNode(path); - else - throw new CmsException("Data " + path + " does not exist"); - page = prefix; - } else { - node = getDefaultNode(session); - page = state; - } - setNode(node); - String title = publishMetaData(node); - - if (log.isTraceEnabled()) - log.trace("node=" + node + ", state=" + state + " (page=" + page + ")"); - - return title; - } catch (Exception e) { - log.error("Cannot set state '" + state + "'", e); - if (previousState.equals("")) - previousState = "~"; - navigateTo(previousState); - throw new CmsException("Unexpected issue when accessing #" + newState, e); - } - } - - private String publishMetaData(Node node) throws RepositoryException { - // Title - String title; - if (node.isNodeType(NodeType.MIX_TITLE) && node.hasProperty(Property.JCR_TITLE)) - title = node.getProperty(Property.JCR_TITLE).getString() + " - " + getBaseTitle(); - else - title = getBaseTitle(); - - HttpServletRequest request = UiContext.getHttpRequest(); - if (request == null) - return null; - - StringBuilder js = new StringBuilder(); - title = title.replace("'", "\\'");// sanitize - js.append("document.title = '" + title + "';"); - jsExecutor.execute(js.toString()); - return title; - } - - // Simply remove some illegal character - // private String clean(String stringToClean) { - // return stringToClean.replaceAll("'", "").replaceAll("\\n", "") - // .replaceAll("\\t", ""); - // } - - protected synchronized Node getNode() { - return node; - } - - private synchronized void setNode(Node node) throws RepositoryException { - this.node = node; - this.nodePath = node == null ? null : node.getPath(); - } - - protected String getState() { - return state; - } - - protected Throwable getException() { - return exception; - } - - protected void resetException() { - exception = null; - } - - protected Session getSession() { - return session; - } - - private class CmsNavigationListener implements BrowserNavigationListener { - private static final long serialVersionUID = -3591018803430389270L; - - @Override - public void navigated(BrowserNavigationEvent event) { - setState(event.getState()); - refresh(); - } - } -} \ No newline at end of file diff --git a/org.argeo.cms/src/org/argeo/cms/CmsConstants.java b/org.argeo.cms/src/org/argeo/cms/CmsConstants.java deleted file mode 100644 index 6f21b57c8..000000000 --- a/org.argeo.cms/src/org/argeo/cms/CmsConstants.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.argeo.cms; - -import org.eclipse.rap.rwt.RWT; -import org.eclipse.swt.graphics.Point; - -/** Commons constants */ -public interface CmsConstants { - // DATAKEYS - public final static String STYLE = RWT.CUSTOM_VARIANT; - public final static String MARKUP = RWT.MARKUP_ENABLED; - public final static String ITEM_HEIGHT = RWT.CUSTOM_ITEM_HEIGHT; - - // EVENT DETAILS - public final static int HYPERLINK = RWT.HYPERLINK; - - // STANDARD RESOURCES - public final static String LOADING_IMAGE = "icons/loading.gif"; - - public final static String NO_IMAGE = "icons/noPic-square-640px.png"; - public final static Point NO_IMAGE_SIZE = new Point(640, 640); - public final static Float NO_IMAGE_RATIO = 1f; -} diff --git a/org.argeo.cms/src/org/argeo/cms/CmsEditable.java b/org.argeo.cms/src/org/argeo/cms/CmsEditable.java deleted file mode 100644 index 3c666ff30..000000000 --- a/org.argeo.cms/src/org/argeo/cms/CmsEditable.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.argeo.cms; - -/** API NOT STABLE (yet). */ -public interface CmsEditable { - - /** Whether the calling thread can edit, the value is immutable */ - public Boolean canEdit(); - - public Boolean isEditing(); - - public void startEditing(); - - public void stopEditing(); - - public static CmsEditable NON_EDITABLE = new CmsEditable() { - - @Override - public void stopEditing() { - } - - @Override - public void startEditing() { - } - - @Override - public Boolean isEditing() { - return false; - } - - @Override - public Boolean canEdit() { - return false; - } - }; - -} diff --git a/org.argeo.cms/src/org/argeo/cms/CmsEditionEvent.java b/org.argeo.cms/src/org/argeo/cms/CmsEditionEvent.java deleted file mode 100644 index 920f6d937..000000000 --- a/org.argeo.cms/src/org/argeo/cms/CmsEditionEvent.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.argeo.cms; - -import java.util.EventObject; - -/** Notify of the edition lifecycle */ -public class CmsEditionEvent extends EventObject { - private static final long serialVersionUID = 950914736016693110L; - - public final static Integer START_EDITING = 0; - public final static Integer STOP_EDITING = 1; - - private final Integer type; - - public CmsEditionEvent(Object source, Integer type) { - super(source); - this.type = type; - } - - public Integer getType() { - return type; - } - -} diff --git a/org.argeo.cms/src/org/argeo/cms/CmsExtension.java b/org.argeo.cms/src/org/argeo/cms/CmsExtension.java deleted file mode 100644 index b574dc51d..000000000 --- a/org.argeo.cms/src/org/argeo/cms/CmsExtension.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.argeo.cms; - -import java.util.List; - -import javax.jcr.Session; - -public interface CmsExtension { - public List getDataModels(); - - public List getRoles(); - - public void onInit(Session adminSession); - - public void onStart(Session adminSession); - - public void onShutdown(Session adminSession); - - public void onDestroy(Session adminSession); -} diff --git a/org.argeo.cms/src/org/argeo/cms/CmsImageManager.java b/org.argeo.cms/src/org/argeo/cms/CmsImageManager.java deleted file mode 100644 index 2577dc777..000000000 --- a/org.argeo.cms/src/org/argeo/cms/CmsImageManager.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.argeo.cms; - -import java.io.InputStream; - -import javax.jcr.Binary; -import javax.jcr.Node; -import javax.jcr.RepositoryException; - -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.widgets.Control; - -/** Read and write access to images. */ -public interface CmsImageManager { - /** Load image in control */ - public Boolean load(Node node, Control control, Point size) - throws RepositoryException; - - /** @return (0,0) if not available */ - public Point getImageSize(Node node) throws RepositoryException; - - /** - * The related workspacesToMigrate(); - -} diff --git a/org.argeo.cms/src/org/argeo/cms/LifeCycleUiProvider.java b/org.argeo.cms/src/org/argeo/cms/LifeCycleUiProvider.java deleted file mode 100644 index bb64b649d..000000000 --- a/org.argeo.cms/src/org/argeo/cms/LifeCycleUiProvider.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.argeo.cms; - -import javax.jcr.RepositoryException; -import javax.jcr.Session; - -/** CmsUiProvider notified of initialisation with a system session. */ -public interface LifeCycleUiProvider extends CmsUiProvider { - public void init(Session adminSession) throws RepositoryException; - - public void destroy(); -} diff --git a/org.argeo.cms/src/org/argeo/cms/UxContext.java b/org.argeo.cms/src/org/argeo/cms/UxContext.java deleted file mode 100644 index b6674b99b..000000000 --- a/org.argeo.cms/src/org/argeo/cms/UxContext.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.argeo.cms; - -public interface UxContext { - boolean isPortrait(); - boolean isLandscape(); - boolean isSquare(); - - boolean isSmall(); -} diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/RepositoryMigration.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/RepositoryMigration.java deleted file mode 100644 index d708f90cb..000000000 --- a/org.argeo.cms/src/org/argeo/cms/internal/backup/RepositoryMigration.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.argeo.cms.internal.backup; - -import java.security.PrivilegedExceptionAction; -import java.util.Map; - -import javax.jcr.Credentials; -import javax.jcr.Repository; -import javax.jcr.RepositoryException; -import javax.jcr.Session; - -import org.argeo.cms.DataMigration; -import org.argeo.jcr.JcrUtils; - -/** Migrate data between two workspaces, at JCR level. */ -public class RepositoryMigration implements PrivilegedExceptionAction { - private final Repository sourceRepository; - private final Repository targetRepository; - private final DataMigration dataMigration; - - private Credentials sourceCredentials = null; - private Credentials targetCredentials = null; - - public RepositoryMigration(Repository sourceRepository, - Repository targetRepository, DataMigration dataMigration) { - this.sourceRepository = sourceRepository; - this.targetRepository = targetRepository; - this.dataMigration = dataMigration; - } - - @Override - public Boolean run() throws Exception { - Map wk = dataMigration.workspacesToMigrate(); - if (wk == null) - return migrate(sourceRepository, null, targetRepository, null); - else { - for (String sourceWorkspace : wk.keySet()) { - String targetWorkspace = wk.get(sourceWorkspace); - boolean ok = migrate(sourceRepository, sourceWorkspace, - targetRepository, targetWorkspace); - if (!ok) - return false; - } - return true; - } - } - - protected final boolean migrate(Repository sourceRepository, - String sourceWorkspace, Repository targetRepository, - String targetWorkspace) throws RepositoryException { - Session source = null, target = null; - try { - source = sourceRepository.login(sourceCredentials, sourceWorkspace); - target = targetRepository.login(targetCredentials, targetWorkspace); - return dataMigration.migrate(source, target); - } finally { - JcrUtils.logoutQuietly(source); - JcrUtils.logoutQuietly(target); - } - } - - public void setSourceCredentials(Credentials sourceCredentials) { - this.sourceCredentials = sourceCredentials; - } - - public void setTargetCredentials(Credentials targetCredentials) { - this.targetCredentials = targetCredentials; - } - -}