diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/bootstrap/site/surf-config.xml b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/bootstrap/site/surf-config.xml new file mode 100644 index 0000000000..85e3048e1a --- /dev/null +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/bootstrap/site/surf-config.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + surf-config + SpacesStore + en_US_ + workspace + false + + + + + + + + + + + + components + SpacesStore + en_US_ + workspace + false + + + + + + + + + + + + page.title.site~${siteId}~dashboard.xml + SpacesStore + en_US_ + contentUrl=surf-config/content0.bin|mimetype=application/octet-stream|size=260|encoding=UTF-8|locale=en_US_ + workspace + false + + + + + + + + + + + page.navigation.site~${siteId}~dashboard.xml + SpacesStore + en_US_ + contentUrl=surf-config/content1.bin|mimetype=application/octet-stream|size=280|encoding=UTF-8|locale=en_US_ + workspace + false + + + + + + + + + + + page.full-width-dashlet.site~${siteId}~dashboard.xml + SpacesStore + en_US_ + contentUrl=surf-config/content2.bin|mimetype=application/octet-stream|size=356|encoding=UTF-8|locale=en_US_ + workspace + false + + + + + + + + + + + page.component-1-1.site~${siteId}~dashboard.xml + SpacesStore + en_US_ + contentUrl=surf-config/content3.bin|mimetype=application/octet-stream|size=326|encoding=UTF-8|locale=en_US_ + workspace + false + + + + + + + + + + + page.component-2-1.site~${siteId}~dashboard.xml + SpacesStore + en_US_ + contentUrl=surf-config/content4.bin|mimetype=application/octet-stream|size=270|encoding=UTF-8|locale=en_US_ + workspace + false + + + + + + + + + + + page.component-2-2.site~${siteId}~dashboard.xml + SpacesStore + en_US_ + contentUrl=surf-config/content5.bin|mimetype=application/octet-stream|size=272|encoding=UTF-8|locale=en_US_ + workspace + false + + + + + + + + + + + + + + pages + SpacesStore + en_US_ + workspace + false + + + + + + + + + + + + site + SpacesStore + en_US_ + workspace + false + + + + + + + + + + + + ${siteId} + SpacesStore + en_US_ + workspace + false + + + + + + + + + + + + dashboard.xml + SpacesStore + en_US_ + contentUrl=surf-config/content6.bin|mimetype=application/octet-stream|size=481|encoding=UTF-8|locale=en_US_ + workspace + false + + + + + + + + + + + + + + + diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/bootstrap/site/surf-config/content0.bin b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/bootstrap/site/surf-config/content0.bin new file mode 100644 index 0000000000..b35212be51 --- /dev/null +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/bootstrap/site/surf-config/content0.bin @@ -0,0 +1,9 @@ + + + + page.title.site~${siteId}~dashboard + page + title + site/${siteId}/dashboard + /components/title/collaboration-title + diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/bootstrap/site/surf-config/content1.bin b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/bootstrap/site/surf-config/content1.bin new file mode 100644 index 0000000000..60826b91f2 --- /dev/null +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/bootstrap/site/surf-config/content1.bin @@ -0,0 +1,9 @@ + + + + page.navigation.site~${siteId}~dashboard + page + navigation + site/${siteId}/dashboard + /components/navigation/collaboration-navigation + diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/bootstrap/site/surf-config/content2.bin b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/bootstrap/site/surf-config/content2.bin new file mode 100644 index 0000000000..a2df728c60 --- /dev/null +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/bootstrap/site/surf-config/content2.bin @@ -0,0 +1,12 @@ + + + + page.full-width-dashlet.site~${siteId}~dashboard + page + full-width-dashlet + site/${siteId}/dashboard + /components/dashlets/dynamic-welcome + + site + + diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/bootstrap/site/surf-config/content3.bin b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/bootstrap/site/surf-config/content3.bin new file mode 100644 index 0000000000..12a81426c2 --- /dev/null +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/bootstrap/site/surf-config/content3.bin @@ -0,0 +1,12 @@ + + + + page.component-1-1.site~${siteId}~dashboard + page + component-1-1 + site/${siteId}/dashboard + /components/dashlets/colleagues + + 504 + + diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/bootstrap/site/surf-config/content4.bin b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/bootstrap/site/surf-config/content4.bin new file mode 100644 index 0000000000..1c5dd174c0 --- /dev/null +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/bootstrap/site/surf-config/content4.bin @@ -0,0 +1,9 @@ + + + + page.component-2-1.site~${siteId}~dashboard + page + component-2-1 + site/${siteId}/dashboard + /components/dashlets/docsummary + diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/bootstrap/site/surf-config/content5.bin b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/bootstrap/site/surf-config/content5.bin new file mode 100644 index 0000000000..c8781e5292 --- /dev/null +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/bootstrap/site/surf-config/content5.bin @@ -0,0 +1,9 @@ + + + + page.component-2-2.site~${siteId}~dashboard + page + component-2-2 + site/${siteId}/dashboard + /components/dashlets/activityfeed + diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/bootstrap/site/surf-config/content6.bin b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/bootstrap/site/surf-config/content6.bin new file mode 100644 index 0000000000..1036e4456f --- /dev/null +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/bootstrap/site/surf-config/content6.bin @@ -0,0 +1,14 @@ + + + + Records Management Site Dashboard + page.rmSiteDashboard.title + Records Management site's dashboard page + page.rmSiteDashboard.description + dashboard-2-columns-wide-right + user + + [{"pageId":"documentlibrary"}, {"pageId":"rm-search"}] + {"documentlibrary":{"titleId":"page.rmDocumentLibrary.title", "descriptionId":"page.rmDocumentLibrary.description", "type":"dod5015"}} + + diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-public-rest-context.xml b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-public-rest-context.xml index 8530dffba2..d9a9d95e60 100644 --- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-public-rest-context.xml +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-public-rest-context.xml @@ -50,4 +50,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + org.alfresco.rest.api.Sites + + + + + + + + + + + + + + \ No newline at end of file diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/rest/api/impl/RMSites.java b/rm-community/rm-community-repo/source/java/org/alfresco/rest/api/impl/RMSites.java new file mode 100644 index 0000000000..cc334dfaa4 --- /dev/null +++ b/rm-community/rm-community-repo/source/java/org/alfresco/rest/api/impl/RMSites.java @@ -0,0 +1,35 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * - + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * - + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ + +package org.alfresco.rest.api.impl; + +import org.alfresco.rest.api.Sites; + +public interface RMSites extends Sites +{ + +} diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/rest/api/impl/RMSitesImpl.java b/rm-community/rm-community-repo/source/java/org/alfresco/rest/api/impl/RMSitesImpl.java new file mode 100644 index 0000000000..8e019a49ee --- /dev/null +++ b/rm-community/rm-community-repo/source/java/org/alfresco/rest/api/impl/RMSitesImpl.java @@ -0,0 +1,214 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * - + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * - + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ + +package org.alfresco.rest.api.impl; + +import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.site.SiteServiceException; +import org.alfresco.rest.api.model.Site; +import org.alfresco.rest.framework.core.exceptions.ConstraintViolatedException; +import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException; +import org.alfresco.rest.framework.resource.parameters.Parameters; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.site.SiteInfo; +import org.alfresco.service.cmr.site.SiteService; +import org.alfresco.service.cmr.site.SiteVisibility; +import org.alfresco.service.cmr.view.ImportPackageHandler; +import org.alfresco.service.cmr.view.ImporterBinding; +import org.alfresco.service.cmr.view.ImporterContentCache; +import org.alfresco.service.cmr.view.ImporterProgress; +import org.alfresco.service.cmr.view.Location; +import org.alfresco.service.namespace.QName; + +/** + * + * @author Silviu Dinuta + * @since 2.6 + * + */ +public class RMSitesImpl extends SitesImpl implements RMSites +{ + private static final int SITE_MAXLEN_ID = 72; + private static final int SITE_MAXLEN_TITLE = 256; + private static final int SITE_MAXLEN_DESCRIPTION = 512; + private static final String SITE_ID_VALID_CHARS_PARTIAL_REGEX = "A-Za-z0-9\\-"; + + @Override + public Site createSite(Site site, Parameters parameters) { + // note: if site id is null then will be generated from the site title + site = validateSite(site); + + SiteInfo siteInfo = null; + try + { + siteInfo = siteService.createSite("rm-site-dashboard", site.getId(), site.getTitle(), site.getDescription(), site.getVisibility(), RecordsManagementModel.TYPE_RM_SITE); + } + catch (SiteServiceException sse) + { + if (sse.getMsgId().equals("site_service.unable_to_create")) + { + throw new ConstraintViolatedException(sse.getMessage()); + } + else + { + throw sse; + } + } + + String siteId = siteInfo.getShortName(); + NodeRef siteNodeRef = siteInfo.getNodeRef(); + + // import default/fixed preset Share surf config + importSite(siteId, siteNodeRef); + + // pre-create doclib + siteService.createContainer(siteId, SiteService.DOCUMENT_LIBRARY, ContentModel.TYPE_FOLDER, null); + + String personId = AuthenticationUtil.getFullyAuthenticatedUser(); + favouritesService.addFavourite(personId, siteNodeRef); // ignore result + + return getSite(siteInfo, true); + } + + private Site getSite(SiteInfo siteInfo, boolean includeRole) + { + // set the site id to the short name (to deal with case sensitivity issues with using the siteId from the url) + String siteId = siteInfo.getShortName(); + String role = null; + if(includeRole) + { + role = getSiteRole(siteId); + } + return new Site(siteInfo, role); + } + + private void importSite(final String siteId, final NodeRef siteNodeRef) + { + ImportPackageHandler acpHandler = new SiteImportPackageHandler(siteSurfConfig, siteId); + Location location = new Location(siteNodeRef); + ImporterBinding binding = new ImporterBinding() + { + @Override + public String getValue(String key) + { + if (key.equals("siteId")) + { + return siteId; + } + return null; + } + + @Override + public UUID_BINDING getUUIDBinding() + { + return UUID_BINDING.CREATE_NEW; + } + + @Override + public QName[] getExcludedClasses() + { + return null; + } + + @Override + public boolean allowReferenceWithinTransaction() + { + return false; + } + + @Override + public ImporterContentCache getImportConentCache() + { + return null; + } + }; + importerService.importView(acpHandler, location, binding, (ImporterProgress)null); + } + + private Site validateSite(Site site) + { + // site title - mandatory + String siteTitle = site.getTitle(); + if ((siteTitle == null) || siteTitle.isEmpty()) + { + throw new InvalidArgumentException("Site title is expected: "+siteTitle); + } + else if (siteTitle.length() > SITE_MAXLEN_TITLE) + { + throw new InvalidArgumentException("Site title exceeds max length of "+SITE_MAXLEN_TITLE+" characters"); + } + + SiteVisibility siteVisibility = site.getVisibility(); + if (siteVisibility == null) + { + throw new InvalidArgumentException("Site visibility is expected: "+siteTitle+" (eg. PUBLIC, PRIVATE, MODERATED)"); + } + + String siteId = site.getId(); + if (siteId == null) + { + // generate a site id from title (similar to Share create site dialog) + siteId = siteTitle. + trim(). // trim leading & trailing whitespace + replaceAll("[^"+SITE_ID_VALID_CHARS_PARTIAL_REGEX+" ]",""). // remove special characters (except spaces) + replaceAll(" +", " "). // collapse multiple spaces to single space + replace(" ","-"). // replaces spaces with dashs + toLowerCase(); // lowercase :-) + } + else + { + if (! siteId.matches("^["+SITE_ID_VALID_CHARS_PARTIAL_REGEX+"]+")) + { + throw new InvalidArgumentException("Invalid site id - should consist of alphanumeric/dash characters"); + } + } + + if (siteId.length() > SITE_MAXLEN_ID) + { + throw new InvalidArgumentException("Site id exceeds max length of "+SITE_MAXLEN_ID+ "characters"); + } + + site.setId(siteId); + + String siteDescription = site.getDescription(); + + if (siteDescription == null) + { + // workaround: to avoid Share error (eg. in My Sites dashlet / freemarker template) + site.setDescription(""); + } + + if ((siteDescription != null) && (siteDescription.length() > SITE_MAXLEN_DESCRIPTION)) + { + throw new InvalidArgumentException("Site description exceeds max length of "+SITE_MAXLEN_DESCRIPTION+" characters"); + } + + return site; + } +} diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/rest/api/sites/RMSiteEntityResource.java b/rm-community/rm-community-repo/source/java/org/alfresco/rest/api/sites/RMSiteEntityResource.java new file mode 100644 index 0000000000..f202f55e78 --- /dev/null +++ b/rm-community/rm-community-repo/source/java/org/alfresco/rest/api/sites/RMSiteEntityResource.java @@ -0,0 +1,80 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * - + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * - + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ + +package org.alfresco.rest.api.sites; + +import java.util.ArrayList; +import java.util.List; + +import org.alfresco.rest.api.Sites; +import org.alfresco.rest.api.model.Site; +import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException; +import org.alfresco.rest.framework.resource.EntityResource; +import org.alfresco.rest.framework.resource.actions.interfaces.EntityResourceAction; +import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo; +import org.alfresco.rest.framework.resource.parameters.Parameters; + +/** + * + * @author Silviu Dinuta + * @since 2.6 + * + */ +@EntityResource(name = "ig-sites", title = "IG Sites") +public class RMSiteEntityResource implements EntityResourceAction.Read, EntityResourceAction.ReadById, + EntityResourceAction.Delete, EntityResourceAction.Create { + + private Sites sites; + + public void setSites(Sites sites) { + this.sites = sites; + } + + @Override + public List create(List entity, Parameters parameters) { + List result = new ArrayList<>(1); + result.add(sites.createSite(entity.get(0), parameters)); + return result; + } + + @Override + public void delete(String id, Parameters parameters) { + sites.deleteSite(id, parameters); + + } + + @Override + public Site readById(String id, Parameters parameters) throws EntityNotFoundException { + return sites.getSite(id); + } + + @Override + public CollectionWithPagingInfo readAll(Parameters params) { + return sites.getSites(params); + } + +} diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/rest/api/sites/package-info.java b/rm-community/rm-community-repo/source/java/org/alfresco/rest/api/sites/package-info.java new file mode 100644 index 0000000000..5a0ec7cb83 --- /dev/null +++ b/rm-community/rm-community-repo/source/java/org/alfresco/rest/api/sites/package-info.java @@ -0,0 +1,37 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * - + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * - + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ + +/** + * Package info that defines the Information Governance sites REST API + * + * @author Silviu Dinuta + * @since 2.6 + */ +@WebApi(name="ig", scope=Api.SCOPE.PUBLIC, version=1) +package org.alfresco.rest.api.sites; +import org.alfresco.rest.framework.Api; +import org.alfresco.rest.framework.WebApi; \ No newline at end of file