Java tutorial
/* * #%L * Alfresco WCMQS Client API * %% * 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 <http://www.gnu.org/licenses/>. * #L% */ package org.alfresco.wcm.client.impl; import java.math.BigInteger; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; import org.alfresco.wcm.client.Asset; import org.alfresco.wcm.client.AssetFactory; import org.alfresco.wcm.client.SectionFactory; import org.alfresco.wcm.client.UgcService; import org.alfresco.wcm.client.WebSite; import org.alfresco.wcm.client.WebSiteService; import org.alfresco.wcm.client.impl.cache.SimpleCache; import org.alfresco.wcm.client.util.CmisSessionHelper; import org.apache.chemistry.opencmis.client.api.ItemIterable; import org.apache.chemistry.opencmis.client.api.QueryResult; import org.apache.chemistry.opencmis.client.api.Session; import org.apache.chemistry.opencmis.commons.PropertyIds; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.json.JSONObject; /** * Web site service implementation * * @author Roy Wetherall * @author Brian Remmington */ public class WebSiteServiceImpl extends WebSiteService { private static final Log log = LogFactory.getLog(WebSiteServiceImpl.class); /** Query for all web sites */ private static final String QUERY_WEB_ROOTS = "select f.cmis:objectId, w.ws:hostName, w.ws:hostPort, t.cm:title, t.cm:description, w.ws:webAppContext, w.ws:siteConfig " + "from cmis:folder as f " + "join ws:website as w on w.cmis:objectId = f.cmis:objectId " + "join cm:titled as t on t.cmis:objectId = f.cmis:objectId"; /** Web site cache */ private Map<String, WebSite> webSiteCache; private long webSiteCacheRefeshedAt; /** Cache timeout values (seconds) */ private int webSiteCacheRefreshAfter = 60; private int webSiteSectionCacheRefreshAfter = 60; private SectionFactory sectionFactory; private AssetFactory assetFactory; private WebScriptCaller webscriptCaller; private SimpleCache<String, String> formIdCache; private String logoFilename; /** * Set the number of seconds after which the web site cache will refresh. * * @param webSiteCacheRefreshAfter * seconds */ public void setWebSiteCacheRefreshAfter(int webSiteCacheRefreshAfter) { this.webSiteCacheRefreshAfter = webSiteCacheRefreshAfter; } /** * Set the number of seconds after which the web site section cache will * refresh. * * @param webSiteSectionCacheRefreshAfter * seconds */ public void setWebSiteSectionCacheRefreshAfter(int webSiteSectionCacheRefreshAfter) { this.webSiteSectionCacheRefreshAfter = webSiteSectionCacheRefreshAfter; } /** * @see org.alfresco.wcm.client.WebSiteService#getWebSite(java.lang.String, * int) */ public WebSite getWebSite(String hostName, int hostPort) { return getWebSite(hostName, hostPort, null); } public WebSite getWebSite(String hostName, int hostPort, String contextPath) { if (contextPath == null) { contextPath = "/"; } else if (!contextPath.startsWith("/")) { contextPath = "/" + contextPath; } String key = (hostName + ":" + hostPort).toLowerCase() + contextPath; WebSite website = getWebSiteCache().get(key); if (website == null) { //It would be fairly unusual for us to have received a request for a specific host and port that //doesn't map to a website in the repo. Could it be that our cache is out of date? //We'll refresh the cache once now just to check. refreshWebsiteCache(); website = getWebSiteCache().get(key); } if (website == null) { log.warn("Received a request for unrecognised host+port: " + key); } return website; } /** * @see org.alfresco.wcm.client.WebSiteService#getWebSites() */ public Collection<WebSite> getWebSites() { return getWebSiteCache().values(); } /** * Gets the web site cache * * @return map of web sites by host:port */ private Map<String, WebSite> getWebSiteCache() { if (webSiteCache == null || webSiteCacheExpired() == true) { refreshWebsiteCache(); } return webSiteCache; } private void refreshWebsiteCache() { Map<String, WebSite> newCache = new HashMap<String, WebSite>(5); Session session = CmisSessionHelper.getSession(); // Execute query if (log.isDebugEnabled()) { log.debug("About to run CMIS query: " + QUERY_WEB_ROOTS); } ItemIterable<QueryResult> results = session.query(QUERY_WEB_ROOTS, false); for (QueryResult result : results) { // Get the details of the returned object String id = result.getPropertyValueById(PropertyIds.OBJECT_ID); String hostName = result.getPropertyValueById(WebSite.PROP_HOSTNAME); BigInteger hostPort = result.getPropertyValueById(WebSite.PROP_HOSTPORT); String context = result.getPropertyValueById(WebSite.PROP_CONTEXT); if (context == null) { context = ""; } if (context.startsWith("/")) { context = context.substring(1); } if (hostPort == null) { // Default to port 80 if not set hostPort = new BigInteger("80"); } String key = (hostName + ":" + hostPort.toString()).toLowerCase() + "/" + context; String title = result.getPropertyValueById(Asset.PROPERTY_TITLE); String description = result.getPropertyValueById(Asset.PROPERTY_DESCRIPTION); List<String> configList = result.getPropertyMultivalueById(WebSite.PROP_SITE_CONFIG); Map<String, String> configProperties = parseSiteConfig(configList); WebsiteInfo siteInfo = getWebsiteInfo(id); WebSiteImpl webSite = new WebSiteImpl(id, hostName, hostPort.intValue(), webSiteSectionCacheRefreshAfter); webSite.setRootSectionId(siteInfo.rootSectionId); webSite.setTitle(title); webSite.setDescription(description); webSite.setContext(context); webSite.setSectionFactory(sectionFactory); webSite.setConfig(configProperties); webSite.setUgcService(createUgcService(session, siteInfo)); newCache.put(key, webSite); // Find the logo asset id Asset logo = assetFactory.getSectionAsset(siteInfo.rootSectionId, logoFilename, true); webSite.setLogo(logo); } webSiteCacheRefeshedAt = System.currentTimeMillis(); webSiteCache = newCache; } protected UgcService createUgcService(Session session, WebsiteInfo siteInfo) { UgcServiceCmisImpl ugcService = new UgcServiceCmisImpl(session.createObjectId(siteInfo.feedbackFolderId)); ugcService.setFormIdCache(formIdCache); return ugcService; } private Map<String, String> parseSiteConfig(List<String> configList) { Map<String, String> result = new TreeMap<String, String>(); if (configList != null) { for (String configValue : configList) { //Make sure we cater for empty values when parsing the name/value pairs String[] split = configValue.split("=", -1); if (split.length == 2) { result.put(split[0], split[1]); } } } return result; } private WebsiteInfo getWebsiteInfo(String websiteid) { String feedbackFolderId = websiteid; String rootSectionId = websiteid; try { WebscriptParam[] params = new WebscriptParam[] { new WebscriptParam("websiteid", websiteid) }; JSONObject jsonObject = webscriptCaller.getJsonObject("websiteinfo", Arrays.asList(params)); if (jsonObject != null) { JSONObject data = (JSONObject) jsonObject.get("data"); feedbackFolderId = data.getString("feedbackfolderid"); rootSectionId = data.getString("rootsectionid"); } } catch (Exception ex) { log.error("Error while attempting to retrieve feedback folder for website " + websiteid, ex); } return new WebsiteInfo(rootSectionId, feedbackFolderId); } /** * Indicates whether the web site cache has expired. * * @return boolean true if expired, false otherwise */ private boolean webSiteCacheExpired() { boolean result = true; long now = System.currentTimeMillis(); long difference = now - webSiteCacheRefeshedAt; long calcValue = webSiteCacheRefreshAfter * 1000; if (difference <= calcValue) { result = false; } return result; } /** * Set the logo image filename pattern, eg logo.% * * @param logoFilename String */ public void setLogoFilename(String logoFilename) { this.logoFilename = logoFilename; } public void setSectionFactory(SectionFactory sectionFactory) { this.sectionFactory = sectionFactory; } public void setAssetFactory(AssetFactory assetFactory) { this.assetFactory = assetFactory; } public void setWebscriptCaller(WebScriptCaller webscriptCaller) { this.webscriptCaller = webscriptCaller; } public void setFormIdCache(SimpleCache<String, String> formIdCache) { this.formIdCache = formIdCache; } public final static class WebsiteInfo { public final String rootSectionId; public final String feedbackFolderId; public WebsiteInfo(String rootSectionId, String feedbackFolderId) { this.rootSectionId = rootSectionId; this.feedbackFolderId = feedbackFolderId; } } }