diff --git a/config/alfresco/messages/webclient.properties b/config/alfresco/messages/webclient.properties index 7ea9751f5e..36445df11e 100644 --- a/config/alfresco/messages/webclient.properties +++ b/config/alfresco/messages/webclient.properties @@ -806,6 +806,7 @@ user_sandboxes=User Sandboxes sandbox_preview=Preview Website sandbox_create=Create New Content sandbox_browse=Browse Website +sandbox_submitall=Submit All sandbox_icon=Browse Website import_website_content=Import Website Content title_browse_sandbox=Browse Sandbox @@ -821,6 +822,8 @@ store_created_by=Created By store_working_users=There are {0} user(s) working on this website. avm_node_deleted=Deleted submit=Submit +submit_success=Successfully submitted item: {0} +submitall_success=Successfully submitted sandbox for user: {0} # Website actions and dialog messages title_import_content=Import Content into Website diff --git a/config/alfresco/web-client-config-wcm-actions.xml b/config/alfresco/web-client-config-wcm-actions.xml index a4f468d723..9962534054 100644 --- a/config/alfresco/web-client-config-wcm-actions.xml +++ b/config/alfresco/web-client-config-wcm-actions.xml @@ -74,6 +74,12 @@ + + + false + + + diff --git a/config/alfresco/web-client-config.xml b/config/alfresco/web-client-config.xml index 37ed10eaf4..cc08dbba01 100644 --- a/config/alfresco/web-client-config.xml +++ b/config/alfresco/web-client-config.xml @@ -65,6 +65,10 @@ alfresco@alfresco.org + + + alfresco.dyndns.org + 8180 diff --git a/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java b/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java index 079a23dbe4..80ab12bf20 100644 --- a/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java +++ b/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java @@ -29,6 +29,7 @@ import javax.faces.context.FacesContext; import javax.faces.event.ActionEvent; import javax.transaction.UserTransaction; +import org.alfresco.config.ConfigService; import org.alfresco.model.ContentModel; import org.alfresco.repo.avm.AVMNodeConverter; import org.alfresco.service.cmr.action.Action; @@ -37,6 +38,7 @@ import org.alfresco.service.cmr.avm.AVMNodeDescriptor; import org.alfresco.service.cmr.avm.AVMService; import org.alfresco.service.cmr.avm.AVMStoreDescriptor; import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.namespace.NamespaceService; @@ -49,6 +51,8 @@ import org.alfresco.web.bean.BrowseBean; import org.alfresco.web.bean.NavigationBean; import org.alfresco.web.bean.repository.Node; import org.alfresco.web.bean.repository.Repository; +import org.alfresco.web.config.ClientConfigElement; +import org.alfresco.web.config.ViewsConfigElement; import org.alfresco.web.ui.common.Utils; import org.alfresco.web.ui.common.component.IBreadcrumbHandler; import org.alfresco.web.ui.common.component.UIActionLink; @@ -73,6 +77,14 @@ public class AVMBrowseBean implements IContextListener private static final String MSG_CREATED_ON = "store_created_on"; private static final String MSG_CREATED_BY = "store_created_by"; private static final String MSG_WORKING_USERS = "store_working_users"; + private static final String MSG_SUBMIT_SUCCESS = "submit_success"; + private static final String MSG_SUBMITALL_SUCCESS = "submitall_success"; + + /** Component id the status messages are tied too */ + private static final String COMPONENT_SANDBOXESPANEL = "sandboxes-panel"; + + /** Action bean Id for the AVM Submit action*/ + private static final String ACTION_AVM_SUBMIT = "simple-avm-submit"; private String sandbox; private String username; @@ -91,6 +103,9 @@ public class AVMBrowseBean implements IContextListener /** Current AVM Node context*/ private AVMNode avmNode = null; + private String wcmDomain; + private String wcmPort; + /** breadcrumb location */ private List location = null; @@ -115,6 +130,7 @@ public class AVMBrowseBean implements IContextListener /** AVM service bean reference */ protected AVMService avmService; + /** Action service bean reference */ protected ActionService actionService; @@ -124,6 +140,10 @@ public class AVMBrowseBean implements IContextListener public AVMBrowseBean() { UIContextService.getInstance(FacesContext.getCurrentInstance()).registerBean(this); + + ClientConfigElement config = Application.getClientConfig(FacesContext.getCurrentInstance()); + this.wcmDomain = config.getWCMDomain(); + this.wcmPort = config.getWCMPort(); } @@ -570,17 +590,21 @@ public class AVMBrowseBean implements IContextListener String path = params.get("id"); if (path != null && path.length() != 0) { - setAVMNodeDescriptor(avmService.lookup(-1, path)); + AVMNodeDescriptor node = avmService.lookup(-1, path, true); + setAVMNodeDescriptor(node); } else { - setAVMNodeDescriptor(null); + setAvmNode(null); } // update UI state ready for return after dialog close UIContextService.getInstance(FacesContext.getCurrentInstance()).notifyBeans(); } + /** + * Submit a node from a user sandbox into the staging area sandbox + */ public void submitNode(ActionEvent event) { setupContentAction(event); @@ -592,17 +616,59 @@ public class AVMBrowseBean implements IContextListener tx = Repository.getUserTransaction(context, true); tx.begin(); - Action action = this.actionService.createAction("simple-avm-submit"); + Action action = this.actionService.createAction(ACTION_AVM_SUBMIT); this.actionService.executeAction(action, getAvmNode().getNodeRef()); // commit the transaction tx.commit(); // if we get here, all was well - output friendly status message to the user - String msg = "Successfully submitted: " + getAvmNode().getName(); + String msg = MessageFormat.format(Application.getMessage( + context, MSG_SUBMIT_SUCCESS), getAvmNode().getName()); FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg); String formId = Utils.getParentForm(context, event.getComponent()).getClientId(context); - context.addMessage(formId + ':' + "sandboxes-panel", facesMsg); + context.addMessage(formId + ':' + COMPONENT_SANDBOXESPANEL, facesMsg); + } + catch (Throwable err) + { + Utils.addErrorMessage(MessageFormat.format(Application.getMessage( + FacesContext.getCurrentInstance(), Repository.ERROR_GENERIC), err.getMessage()), err); + try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} + } + } + + /** + * Submit an entire user sandbox + */ + public void submitAll(ActionEvent event) + { + UIActionLink link = (UIActionLink)event.getComponent(); + Map params = link.getParameterMap(); + String store = params.get("store"); + String username = params.get("username"); + + String rootPath = AVMConstants.buildAVMStoreRootPath(store); + NodeRef rootRef = AVMNodeConverter.ToNodeRef(-1, rootPath); + + UserTransaction tx = null; + try + { + FacesContext context = FacesContext.getCurrentInstance(); + tx = Repository.getUserTransaction(context, true); + tx.begin(); + + Action action = this.actionService.createAction(ACTION_AVM_SUBMIT); + this.actionService.executeAction(action, rootRef); + + // commit the transaction + tx.commit(); + + // if we get here, all was well - output friendly status message to the user + String msg = MessageFormat.format(Application.getMessage( + context, MSG_SUBMITALL_SUCCESS), username); + FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg); + String formId = Utils.getParentForm(context, event.getComponent()).getClientId(context); + context.addMessage(formId + ':' + COMPONENT_SANDBOXESPANEL, facesMsg); } catch (Throwable err) { diff --git a/source/java/org/alfresco/web/bean/wcm/AVMNode.java b/source/java/org/alfresco/web/bean/wcm/AVMNode.java index 3b0ca41a20..8809be6f07 100644 --- a/source/java/org/alfresco/web/bean/wcm/AVMNode.java +++ b/source/java/org/alfresco/web/bean/wcm/AVMNode.java @@ -30,6 +30,7 @@ import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QNameMap; import org.alfresco.web.bean.repository.Repository; +import sun.security.krb5.internal.av; /** * @author Kevin Roast @@ -41,6 +42,7 @@ public class AVMNode implements Map private AVMNodeDescriptor avmRef; private String path; private int version; + private boolean deleted = false; /** @@ -51,8 +53,12 @@ public class AVMNode implements Map this.avmRef = avmRef; this.version = -1; // TODO: always -1 for now... this.path = avmRef.getPath(); - - getProperties(); + } + + public AVMNode(AVMNodeDescriptor avmRef, boolean deleted) + { + this(avmRef); + this.deleted = deleted; } public String getPath() @@ -82,13 +88,16 @@ public class AVMNode implements Map { if (this.properties == null) { - Map props = getServiceRegistry().getAVMService().getNodeProperties(this.version, this.path); - this.properties = new QNameMap(getServiceRegistry().getNamespaceService()); - for (QName qname: props.keySet()) + + if (this.deleted == false) { - PropertyValue propValue = props.get(qname); - this.properties.put(qname.toString(), propValue.getSerializableValue()); + Map props = getServiceRegistry().getAVMService().getNodeProperties(this.version, this.path); + for (QName qname: props.keySet()) + { + PropertyValue propValue = props.get(qname); + this.properties.put(qname.toString(), propValue.getSerializableValue()); + } } this.properties.put("id", this.path); diff --git a/source/java/org/alfresco/web/bean/wcm/ImportWebsiteDialog.java b/source/java/org/alfresco/web/bean/wcm/ImportWebsiteDialog.java index 94206188bf..3ebd128a8d 100644 --- a/source/java/org/alfresco/web/bean/wcm/ImportWebsiteDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/ImportWebsiteDialog.java @@ -191,9 +191,7 @@ public class ImportWebsiteDialog tx = Repository.getUserTransaction(context); tx.begin(); - // - // TODO: import the content into the appropriate store for the website - // + // import the content into the appropriate store for the website String storeRoot = (String)this.navigationBean.getCurrentNode().getProperties().get( ContentModel.PROP_AVMSTORE); if (storeRoot != null) @@ -207,6 +205,7 @@ public class ImportWebsiteDialog // convert the AVM path to a NodeRef so we can use the NodeService to perform import NodeRef importRef = AVMNodeConverter.ToNodeRef(-1, rootPath); processZipImport(this.file, importRef); + // After an import it's a good idea to snapshot the staging store this.avmService.createSnapshot(store); } diff --git a/source/java/org/alfresco/web/config/ClientConfigElement.java b/source/java/org/alfresco/web/config/ClientConfigElement.java index b151b3b0fe..eba6408ad9 100644 --- a/source/java/org/alfresco/web/config/ClientConfigElement.java +++ b/source/java/org/alfresco/web/config/ClientConfigElement.java @@ -41,6 +41,8 @@ public class ClientConfigElement extends ConfigElementAdapter private String homeSpacePermission = null; private boolean ajaxEnabled = false; private String initialLocation = "myalfresco"; + private String wcmDomain = null; + private String wcmPort = null; /** * Default Constructor @@ -157,6 +159,24 @@ public class ClientConfigElement extends ConfigElementAdapter combinedElement.setInitialLocation(newElement.getInitialLocation()); } + if (newElement.getWCMDomain() == null) + { + combinedElement.setWCMDomain(this.wcmDomain); + } + else + { + combinedElement.setWCMDomain(newElement.wcmDomain); + } + + if (newElement.getWCMPort() == null) + { + combinedElement.setWCMPort(this.wcmPort); + } + else + { + combinedElement.setWCMPort(newElement.wcmPort); + } + return combinedElement; } @@ -376,4 +396,36 @@ public class ClientConfigElement extends ConfigElementAdapter { this.initialLocation = initialLocation; } + + /** + * @return Returns the WCM Domain. + */ + public String getWCMDomain() + { + return this.wcmDomain; + } + + /** + * @param wcmDomain The WCM Domain to set. + */ + /*package*/ void setWCMDomain(String wcmDomain) + { + this.wcmDomain = wcmDomain; + } + + /** + * @return Returns the WCM Port. + */ + public String getWCMPort() + { + return this.wcmPort; + } + + /** + * @param wcmPort The WCM Port to set. + */ + /*package*/ void setWCMPort(String wcmPort) + { + this.wcmPort = wcmPort; + } } diff --git a/source/java/org/alfresco/web/config/ClientElementReader.java b/source/java/org/alfresco/web/config/ClientElementReader.java index 43d25005ee..593112d366 100644 --- a/source/java/org/alfresco/web/config/ClientElementReader.java +++ b/source/java/org/alfresco/web/config/ClientElementReader.java @@ -41,6 +41,8 @@ public class ClientElementReader implements ConfigElementReader public static final String ELEMENT_SHELFVISIBLE = "shelf-visible"; public static final String ELEMENT_AJAX_ENABLED = "ajax-enabled"; public static final String ELEMENT_INITIALLOCATION = "initial-location"; + public static final String ELEMENT_WCM_DOMAIN = "wcm-domain"; + public static final String ELEMENT_WCM_PORT = "wcm-port"; /** * @see org.alfresco.config.xml.elementreader.ConfigElementReader#parse(org.dom4j.Element) @@ -152,6 +154,18 @@ public class ClientElementReader implements ConfigElementReader { configElement.setInitialLocation(initialLocation.getTextTrim()); } + + // get the WCM domain and port + Element wcmDomain = element.element(ELEMENT_WCM_DOMAIN); + if (wcmDomain != null) + { + configElement.setWCMDomain(wcmDomain.getTextTrim()); + } + Element wcmPort = element.element(ELEMENT_WCM_PORT); + if (wcmPort != null) + { + configElement.setWCMPort(wcmPort.getTextTrim()); + } } return configElement; diff --git a/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java b/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java index a096f306ce..84ac311853 100644 --- a/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java +++ b/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java @@ -64,6 +64,7 @@ public class UIUserSandboxes extends SelfRenderingComponent { private static final String ACTIONS_FILE = "avm_file_modified"; private static final String ACTIONS_FOLDER = "avm_folder_modified"; + private static final String ACTIONS_DELETED = "avm_deleted_modified"; private static final String COMPONENT_ACTIONS = "org.alfresco.faces.Actions"; @@ -231,6 +232,11 @@ public class UIUserSandboxes extends SelfRenderingComponent "#{AVMBrowseBean.setupSandboxAction}", "wizard:createWebContent")); out.write(" "); + Utils.encodeRecursive(context, aquireAction( + context, mainStore, username, "sandbox_submitall", "/images/icons/submit.gif", + "#{AVMBrowseBean.submitAll}", null)); + out.write(" "); + Utils.encodeRecursive(context, aquireAction( context, mainStore, username, "sandbox_browse", "/images/icons/space_small.gif", "#{AVMBrowseBean.setupSandboxAction}", "browseSandbox")); @@ -303,9 +309,10 @@ public class UIUserSandboxes extends SelfRenderingComponent String stagingStore = AVMConstants.buildAVMStagingStoreName(storeRoot) + ":/"; // get the UIActions component responsible for rendering context related user actions - // TODO: we may need a component per user instance + // TODO: we may need a component per user instance? (or use evaluators for roles...) UIActions uiFileActions = aquireUIActions(ACTIONS_FILE); UIActions uiFolderActions = aquireUIActions(ACTIONS_FOLDER); + UIActions uiDeletedActions = aquireUIActions(ACTIONS_DELETED); // use the sync service to get the list of diffs between the stores List diffs = avmSyncService.compare(-1, userStore, -1, stagingStore); @@ -391,7 +398,7 @@ public class UIUserSandboxes extends SelfRenderingComponent else { // must have been deleted from this sandbox - show ghosted - AVMNodeDescriptor ghost = avmService.lookup(-1, diff.getDestinationPath()); + AVMNodeDescriptor ghost = avmService.lookup(-1, diff.getSourcePath(), true); if (ghost != null) { // icon and name of the file/folder - files are clickable to see the content @@ -401,14 +408,14 @@ public class UIUserSandboxes extends SelfRenderingComponent { out.write(Utils.buildImageTag(fc, Utils.getFileTypeImage(fc, name, true), "")); out.write(""); - out.write(name); + out.write(name + " [" + bundle.getString(MSG_DELETED_ITEM) + "]"); out.write(""); } else { out.write(Utils.buildImageTag(fc, SPACE_ICON, 16, 16, "")); out.write(""); - out.write(name); + out.write(name + " [" + bundle.getString(MSG_DELETED_ITEM) + "]"); } out.write(""); @@ -427,8 +434,10 @@ public class UIUserSandboxes extends SelfRenderingComponent } out.write(""); - // no UI actions for this item - out.write('[' + bundle.getString(MSG_DELETED_ITEM) + ']'); + // deleted UI actions for this item + uiDeletedActions.setContext(new AVMNode(ghost, true)); + Utils.encodeRecursive(fc, uiDeletedActions); + out.write(""); } }