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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
--- /dev/null
+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<String, String> 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<String, String> factoryProperties) {
+ this.repository = repository;
+ this.workspace = workspace;
+ this.defaultPath = defaultPath;
+ this.factoryProperties = new HashMap<String, String>(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<Void>() {
+ @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<Void>() {
+
+ @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<Void>() {
+ @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
--- /dev/null
+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;
+}
--- /dev/null
+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;
+ }
+ };
+
+}
--- /dev/null
+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;
+ }
+
+}
--- /dev/null
+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 <img tag, with src, width and height set. @return null if not
+ * available
+ */
+ public String getImageTag(Node node) throws RepositoryException;
+
+ /**
+ * The related <img tag, with url, width and height set. Caller must close
+ * the tag (or add additional attributes). @return null if not available
+ */
+ public StringBuilder getImageTagBuilder(Node node, Point size)
+ throws RepositoryException;
+
+ /**
+ * Returns the remotely accessible URL of the image (registering it if
+ * needed) @return null if not available
+ */
+ public String getImageUrl(Node node) throws RepositoryException;
+
+ public Binary getImageBinary(Node node) throws RepositoryException;
+
+ public Image getSwtImage(Node node) throws RepositoryException;
+
+ /** @return URL */
+ public String uploadImage(Node parentNode, String fileName, InputStream in)
+ throws RepositoryException;
+}
--- /dev/null
+package org.argeo.cms.ui;
+
+/** Styles references in the CSS. */
+public interface CmsStyles {
+ // General
+ public final static String CMS_SHELL = "cms_shell";
+ public final static String CMS_MENU_LINK = "cms_menu_link";
+
+ // Header
+ public final static String CMS_HEADER = "cms_header";
+ public final static String CMS_HEADER_LEAD = "cms_header-lead";
+ public final static String CMS_HEADER_CENTER = "cms_header-center";
+ public final static String CMS_HEADER_END = "cms_header-end";
+ public final static String CMS_USER_MENU = "cms_user_menu";
+ public final static String CMS_USER_MENU_LINK = "cms_user_menu-link";
+ public final static String CMS_USER_MENU_ITEM = "cms_user_menu-item";
+ public final static String CMS_LOGIN_DIALOG = "cms_login_dialog";
+ public final static String CMS_LOGIN_DIALOG_USERNAME = "cms_login_dialog-username";
+ public final static String CMS_LOGIN_DIALOG_PASSWORD = "cms_login_dialog-password";
+
+ // Body
+ public final static String CMS_SCROLLED_AREA = "cms_scrolled_area";
+ public final static String CMS_BODY = "cms_body";
+ public final static String CMS_STATIC_TEXT = "cms_static-text";
+ public final static String CMS_LINK = "cms_link";
+}
--- /dev/null
+package org.argeo.cms.ui;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+/** Stateless factory building an SWT user interface given a JCR context. */
+public interface CmsUiProvider {
+ /**
+ * Initialises a user interface.
+ *
+ * @param parent
+ * the parent composite
+ * @param a
+ * context node or null
+ */
+ public Control createUi(Composite parent, Node context)
+ throws RepositoryException;
+}
--- /dev/null
+package org.argeo.cms.ui;
+
+import javax.security.auth.login.LoginContext;
+
+import org.argeo.node.NodeAuthenticated;
+
+/** Provides interaction with the CMS system. UNSTABLE API at this stage. */
+public interface CmsView extends NodeAuthenticated {
+ UxContext getUxContext();
+
+ // NAVIGATION
+ void navigateTo(String state);
+
+ // SECURITY
+ void authChange(LoginContext loginContext);
+
+ void logout();
+
+ // SERVICES
+ void exception(Throwable e);
+
+ CmsImageManager getImageManager();
+}
--- /dev/null
+package org.argeo.cms.ui;
+
+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();
+}
--- /dev/null
+package org.argeo.cms.ui;
+
+public interface UxContext {
+ boolean isPortrait();
+ boolean isLandscape();
+ boolean isSquare();
+
+ boolean isSmall();
+}
package org.argeo.cms.ui.internal;
-import org.argeo.cms.CmsStyles;
import org.argeo.cms.maintenance.MaintenanceUi;
+import org.argeo.cms.ui.CmsStyles;
import org.argeo.cms.ui.internal.rwt.UserUi;
import org.argeo.node.NodeState;
import org.argeo.util.LangUtils;
import static javax.jcr.Property.JCR_DATA;
import static javax.jcr.nodetype.NodeType.NT_FILE;
import static javax.jcr.nodetype.NodeType.NT_RESOURCE;
-import static org.argeo.cms.CmsConstants.NO_IMAGE_SIZE;
import static org.argeo.cms.CmsTypes.CMS_STYLED;
+import static org.argeo.cms.ui.CmsConstants.NO_IMAGE_SIZE;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.argeo.cms.CmsException;
-import org.argeo.cms.CmsImageManager;
import org.argeo.cms.CmsNames;
import org.argeo.cms.CmsTypes;
+import org.argeo.cms.ui.CmsImageManager;
import org.argeo.cms.util.CmsUtils;
import org.argeo.jcr.JcrUtils;
import org.eclipse.rap.rwt.RWT;
import org.apache.commons.io.FilenameUtils;
import org.argeo.cms.CmsException;
-import org.argeo.cms.CmsImageManager;
import org.argeo.cms.CmsNames;
+import org.argeo.cms.ui.CmsImageManager;
import org.argeo.jcr.JcrUtils;
import org.eclipse.rap.fileupload.FileDetails;
import org.eclipse.rap.fileupload.FileUploadReceiver;
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.CmsTypes;
import org.argeo.cms.text.Img;
import org.argeo.cms.text.Paragraph;
import org.argeo.cms.text.TextInterpreter;
import org.argeo.cms.text.TextSection;
+import org.argeo.cms.ui.CmsEditable;
+import org.argeo.cms.ui.CmsImageManager;
import org.argeo.cms.util.CmsUtils;
import org.argeo.cms.viewers.AbstractPageViewer;
import org.argeo.cms.viewers.EditablePart;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.argeo.cms.CmsException;
-import org.argeo.cms.CmsStyles;
-import org.argeo.cms.CmsUiProvider;
+import org.argeo.cms.ui.CmsStyles;
+import org.argeo.cms.ui.CmsUiProvider;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.rap.rwt.service.ResourceManager;
import org.eclipse.swt.SWT;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.argeo.cms.CmsConstants;
import org.argeo.cms.CmsException;
-import org.argeo.cms.CmsView;
import org.argeo.cms.auth.AuthConstants;
+import org.argeo.cms.ui.CmsConstants;
+import org.argeo.cms.ui.CmsView;
import org.argeo.eclipse.ui.specific.UiContext;
import org.argeo.jcr.ArgeoJcrConstants;
import org.argeo.jcr.JcrUtils;
import javax.servlet.http.HttpServletRequest;
import org.argeo.cms.CmsException;
-import org.argeo.cms.CmsImageManager;
-import org.argeo.cms.CmsView;
-import org.argeo.cms.UxContext;
import org.argeo.cms.auth.AuthConstants;
import org.argeo.cms.auth.CurrentUser;
import org.argeo.cms.auth.HttpRequestCallbackHandler;
+import org.argeo.cms.ui.CmsImageManager;
+import org.argeo.cms.ui.CmsView;
+import org.argeo.cms.ui.UxContext;
import org.argeo.cms.widgets.auth.CmsLogin;
import org.argeo.cms.widgets.auth.CmsLoginShell;
import org.argeo.eclipse.ui.specific.UiContext;
package org.argeo.cms.util;
-import org.argeo.cms.CmsStyles;
+import org.argeo.cms.ui.CmsStyles;
/**
* Convenience class setting the custom style {@link CmsStyles#CMS_MENU_LINK} on
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.argeo.cms.CmsConstants;
import org.argeo.cms.CmsException;
-import org.argeo.cms.CmsUiProvider;
-import org.argeo.cms.LifeCycleUiProvider;
+import org.argeo.cms.ui.CmsConstants;
+import org.argeo.cms.ui.CmsUiProvider;
+import org.argeo.cms.ui.LifeCycleUiProvider;
import org.argeo.jcr.JcrUtils;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.rap.rwt.application.Application;
import javax.jcr.RepositoryException;
import org.argeo.cms.CmsException;
-import org.argeo.cms.CmsStyles;
-import org.argeo.cms.CmsUiProvider;
+import org.argeo.cms.ui.CmsStyles;
+import org.argeo.cms.ui.CmsUiProvider;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import javax.jcr.Value;
import org.argeo.cms.CmsException;
-import org.argeo.cms.CmsUiProvider;
+import org.argeo.cms.ui.CmsUiProvider;
import org.argeo.jcr.JcrUtils;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.swt.SWT;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.argeo.cms.AbstractCmsEntryPoint;
import org.argeo.cms.CmsException;
-import org.argeo.cms.CmsImageManager;
-import org.argeo.cms.CmsStyles;
-import org.argeo.cms.CmsUiProvider;
-import org.argeo.cms.UxContext;
+import org.argeo.cms.ui.AbstractCmsEntryPoint;
+import org.argeo.cms.ui.CmsImageManager;
+import org.argeo.cms.ui.CmsStyles;
+import org.argeo.cms.ui.CmsUiProvider;
+import org.argeo.cms.ui.UxContext;
import org.argeo.cms.ui.internal.ImageManagerImpl;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.swt.SWT;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
-import org.argeo.cms.CmsStyles;
-import org.argeo.cms.CmsUiProvider;
+import org.argeo.cms.ui.CmsStyles;
+import org.argeo.cms.ui.CmsUiProvider;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
package org.argeo.cms.util;
-import org.argeo.cms.UxContext;
+import org.argeo.cms.ui.UxContext;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;
import org.apache.commons.io.IOUtils;
import org.argeo.cms.CmsException;
-import org.argeo.cms.CmsStyles;
+import org.argeo.cms.ui.CmsStyles;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import javax.security.auth.Subject;
import org.argeo.cms.CmsMsg;
-import org.argeo.cms.CmsStyles;
import org.argeo.cms.auth.AuthConstants;
import org.argeo.cms.auth.CurrentUser;
+import org.argeo.cms.ui.CmsStyles;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseEvent;
import javax.security.auth.x500.X500Principal;
import org.argeo.cms.CmsException;
-import org.argeo.cms.CmsView;
import org.argeo.cms.auth.AuthConstants;
import org.argeo.cms.auth.CurrentUser;
+import org.argeo.cms.ui.CmsView;
import org.argeo.cms.util.CmsUtils;
import org.argeo.eclipse.ui.EclipseUiUtils;
import org.argeo.jcr.JcrUtils;
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.ui.CmsEditable;
import org.argeo.cms.widgets.ScrolledPage;
import org.eclipse.jface.viewers.ContentViewer;
import org.eclipse.jface.viewers.ISelection;
import javax.jcr.nodetype.NodeType;
import javax.jcr.version.VersionManager;
-import org.argeo.cms.CmsEditable;
-import org.argeo.cms.CmsEditionEvent;
import org.argeo.cms.CmsException;
+import org.argeo.cms.ui.CmsEditable;
+import org.argeo.cms.ui.CmsEditionEvent;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import javax.jcr.Item;
import javax.jcr.RepositoryException;
-import org.argeo.cms.CmsConstants;
import org.argeo.cms.CmsNames;
+import org.argeo.cms.ui.CmsConstants;
import org.argeo.cms.util.CmsUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.argeo.cms.CmsMsg;
-import org.argeo.cms.CmsStyles;
-import org.argeo.cms.CmsView;
import org.argeo.cms.auth.CurrentUser;
import org.argeo.cms.auth.HttpRequestCallback;
import org.argeo.cms.i18n.LocaleUtils;
+import org.argeo.cms.ui.CmsStyles;
+import org.argeo.cms.ui.CmsView;
import org.argeo.cms.ui.internal.Activator;
import org.argeo.cms.util.CmsUtils;
import org.eclipse.rap.rwt.RWT;
package org.argeo.cms.widgets.auth;
-import org.argeo.cms.CmsView;
+import org.argeo.cms.ui.CmsView;
import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.swt.SWT;
+++ /dev/null
-package org.argeo.cms;
-
-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.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<String, String> 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<String, String> factoryProperties) {
- this.repository = repository;
- this.workspace = workspace;
- this.defaultPath = defaultPath;
- this.factoryProperties = new HashMap<String, String>(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<Void>() {
- @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<Void>() {
-
- @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<Void>() {
- @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
+++ /dev/null
-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;
-}
+++ /dev/null
-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;
- }
- };
-
-}
+++ /dev/null
-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;
- }
-
-}
+++ /dev/null
-package org.argeo.cms;
-
-import java.util.List;
-
-import javax.jcr.Session;
-
-public interface CmsExtension {
- public List<String> getDataModels();
-
- public List<String> getRoles();
-
- public void onInit(Session adminSession);
-
- public void onStart(Session adminSession);
-
- public void onShutdown(Session adminSession);
-
- public void onDestroy(Session adminSession);
-}
+++ /dev/null
-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 <img tag, with src, width and height set. @return null if not
- * available
- */
- public String getImageTag(Node node) throws RepositoryException;
-
- /**
- * The related <img tag, with url, width and height set. Caller must close
- * the tag (or add additional attributes). @return null if not available
- */
- public StringBuilder getImageTagBuilder(Node node, Point size)
- throws RepositoryException;
-
- /**
- * Returns the remotely accessible URL of the image (registering it if
- * needed) @return null if not available
- */
- public String getImageUrl(Node node) throws RepositoryException;
-
- public Binary getImageBinary(Node node) throws RepositoryException;
-
- public Image getSwtImage(Node node) throws RepositoryException;
-
- /** @return URL */
- public String uploadImage(Node parentNode, String fileName, InputStream in)
- throws RepositoryException;
-}
+++ /dev/null
-package org.argeo.cms;
-
-/** Styles references in the CSS. */
-public interface CmsStyles {
- // General
- public final static String CMS_SHELL = "cms_shell";
- public final static String CMS_MENU_LINK = "cms_menu_link";
-
- // Header
- public final static String CMS_HEADER = "cms_header";
- public final static String CMS_HEADER_LEAD = "cms_header-lead";
- public final static String CMS_HEADER_CENTER = "cms_header-center";
- public final static String CMS_HEADER_END = "cms_header-end";
- public final static String CMS_USER_MENU = "cms_user_menu";
- public final static String CMS_USER_MENU_LINK = "cms_user_menu-link";
- public final static String CMS_USER_MENU_ITEM = "cms_user_menu-item";
- public final static String CMS_LOGIN_DIALOG = "cms_login_dialog";
- public final static String CMS_LOGIN_DIALOG_USERNAME = "cms_login_dialog-username";
- public final static String CMS_LOGIN_DIALOG_PASSWORD = "cms_login_dialog-password";
-
- // Body
- public final static String CMS_SCROLLED_AREA = "cms_scrolled_area";
- public final static String CMS_BODY = "cms_body";
- public final static String CMS_STATIC_TEXT = "cms_static-text";
- public final static String CMS_LINK = "cms_link";
-}
+++ /dev/null
-package org.argeo.cms;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-
-/** Stateless factory building an SWT user interface given a JCR context. */
-public interface CmsUiProvider {
- /**
- * Initialises a user interface.
- *
- * @param parent
- * the parent composite
- * @param a
- * context node or null
- */
- public Control createUi(Composite parent, Node context)
- throws RepositoryException;
-}
+++ /dev/null
-package org.argeo.cms;
-
-import javax.security.auth.login.LoginContext;
-
-import org.argeo.node.NodeAuthenticated;
-
-/** Provides interaction with the CMS system. UNSTABLE API at this stage. */
-public interface CmsView extends NodeAuthenticated {
- UxContext getUxContext();
-
- // NAVIGATION
- void navigateTo(String state);
-
- // SECURITY
- void authChange(LoginContext loginContext);
-
- void logout();
-
- // SERVICES
- void exception(Throwable e);
-
- CmsImageManager getImageManager();
-}
+++ /dev/null
-package org.argeo.cms;
-
-import java.util.Map;
-
-import javax.jcr.Session;
-
-public interface DataMigration {
- /** Migrate data between two workspaces, at JCR level. */
- Boolean migrate(Session source, Session target);
-
- /**
- * Keys are the source workspaces and values the target workspaces. If null
- * is returned, only the default workspace will be migrated, to the default
- * workspace of the target repository.
- */
- Map<String, String> workspacesToMigrate();
-
-}
+++ /dev/null
-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();
-}
+++ /dev/null
-package org.argeo.cms;
-
-public interface UxContext {
- boolean isPortrait();
- boolean isLandscape();
- boolean isSquare();
-
- boolean isSmall();
-}
+++ /dev/null
-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<Boolean> {
- 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<String, String> 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;
- }
-
-}