package com.constellio.app.modules.rm.ui.util; import static com.constellio.app.utils.HttpRequestUtils.isLocalhost; import static com.constellio.app.utils.HttpRequestUtils.isMacOsX; import static com.constellio.app.utils.HttpRequestUtils.isWindows; import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URLDecoder; import java.net.URLEncoder; import javax.servlet.http.HttpServletRequest; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang3.StringUtils; import com.constellio.app.modules.rm.RMConfigs; import com.constellio.app.modules.rm.wrappers.Document; import com.constellio.app.services.factories.ConstellioFactories; import com.constellio.app.ui.application.ConstellioUI; import com.constellio.app.ui.entities.ContentVersionVO; import com.constellio.app.ui.entities.RecordVO; import com.constellio.app.ui.entities.UserDocumentVO; import com.constellio.app.ui.entities.UserVO; import com.constellio.app.ui.pages.base.SessionContext; import com.constellio.app.utils.HttpRequestUtils; import com.constellio.data.utils.UnicodeUtils; import com.constellio.model.conf.FoldersLocator; import com.constellio.model.entities.records.Content; import com.constellio.model.entities.records.Record; import com.constellio.model.entities.records.wrappers.UserDocument; import com.constellio.model.entities.schemas.MetadataSchemaTypes; import com.constellio.model.entities.security.global.AgentStatus; import com.constellio.model.entities.security.global.SolrUserCredential; import com.constellio.model.services.configs.SystemConfigurationsManager; import com.constellio.model.services.factories.ModelLayerFactory; import com.constellio.model.services.records.RecordServices; import com.constellio.model.services.schemas.MetadataSchemasManager; import com.constellio.model.services.schemas.SchemaUtils; import com.constellio.model.services.users.UserServices; import com.vaadin.server.Page; import com.vaadin.server.VaadinServlet; import com.vaadin.server.VaadinServletService; public class ConstellioAgentUtils { public static final String URL_SEP = "agentURLSep"; public static final String AGENT_DOWNLOAD_URL = "http://constellio.com/agent/"; public static boolean isAgentSupported() { return isAgentSupported(null); } public static boolean isAgentSupported(HttpServletRequest request) { if (request == null) { request = VaadinServletService.getCurrentServletRequest(); } return request != null && (isWindows(request) || isMacOsX(request) || isLocalhost(request)); } public static String getAgentBaseURL() { return getAgentBaseURL(null); } public static String getAgentBaseURL(HttpServletRequest request) { String agentBaseURL; // FIXME Should not obtain ConstellioFactories through singleton ModelLayerFactory modelLayerFactory = ConstellioFactories.getInstance().getModelLayerFactory(); SystemConfigurationsManager systemConfigurationsManager = modelLayerFactory.getSystemConfigurationsManager(); RMConfigs rmConfigs = new RMConfigs(systemConfigurationsManager); if (rmConfigs.isAgentEnabled()) { String baseURL; if (request != null) { baseURL = HttpRequestUtils.getBaseURL(request, true); } else { Page page = Page.getCurrent(); URI location = page.getLocation(); String contextPath = VaadinServlet.getCurrent().getServletContext().getContextPath(); String schemeSpecificPart = location.getSchemeSpecificPart().substring(2); String schemeSpecificPartBeforeContextPath; if (StringUtils.isNotBlank(contextPath)) { if (schemeSpecificPart.indexOf(contextPath) != -1) { schemeSpecificPartBeforeContextPath = StringUtils.substringBeforeLast(schemeSpecificPart, contextPath); } else { contextPath = null; schemeSpecificPartBeforeContextPath = StringUtils.removeEnd(schemeSpecificPart, "/"); } } else { schemeSpecificPartBeforeContextPath = StringUtils.removeEnd(schemeSpecificPart, "/"); } StringBuffer baseURLSB = new StringBuffer(); baseURLSB.append(location.getScheme()); baseURLSB.append("://"); baseURLSB.append(schemeSpecificPartBeforeContextPath); if (StringUtils.isNotBlank(contextPath)) { baseURLSB.append(contextPath); } baseURL = baseURLSB.toString(); } StringBuffer sb = new StringBuffer(); sb.append(baseURL); sb.append("/agentPath"); agentBaseURL = sb.toString(); } else { agentBaseURL = null; } return agentBaseURL; } public static String getAgentInitURL() { return getAgentInitURL(null); } public static String getAgentInitURL(HttpServletRequest request) { String agentBaseURL = getAgentBaseURL(request); return addConstellioProtocol(agentBaseURL, request); } public static String getAgentURL(RecordVO recordVO, ContentVersionVO contentVersionVO) { SessionContext sessionContext = ConstellioUI.getCurrentSessionContext(); return getAgentURL(recordVO, contentVersionVO, null, sessionContext); } public static String getAgentURL(RecordVO recordVO, ContentVersionVO contentVersionVO, SessionContext sessionContext) { return getAgentURL(recordVO, contentVersionVO, null, sessionContext); } public static String getAgentURL(RecordVO recordVO, ContentVersionVO contentVersionVO, HttpServletRequest request, SessionContext sessionContext) { String agentURL; if (recordVO != null && contentVersionVO != null && isAgentSupported(request)) { // FIXME Should not obtain ConstellioFactories through singleton ModelLayerFactory modelLayerFactory = ConstellioFactories.getInstance().getModelLayerFactory(); SystemConfigurationsManager systemConfigurationsManager = modelLayerFactory.getSystemConfigurationsManager(); RMConfigs rmConfigs = new RMConfigs(systemConfigurationsManager); UserVO userVO = sessionContext.getCurrentUser(); UserServices userServices = modelLayerFactory.newUserServices(); SolrUserCredential userCredentials = (SolrUserCredential) userServices.getUser(userVO.getUsername()); AgentStatus agentStatus = userCredentials.getAgentStatus(); if (agentStatus == AgentStatus.DISABLED && !rmConfigs.isAgentDisabledUntilFirstConnection()) { agentStatus = AgentStatus.ENABLED; } if (rmConfigs.isAgentEnabled() && agentStatus == AgentStatus.ENABLED && (!(recordVO instanceof UserDocumentVO) || rmConfigs.isAgentEditUserDocuments())) { String resourcePath = getResourcePath(recordVO, contentVersionVO, sessionContext); if (resourcePath != null) { String agentBaseURL = getAgentBaseURL(request); StringBuffer sb = new StringBuffer(); sb.append(agentBaseURL); sb.append(resourcePath); agentURL = sb.toString(); } else { agentURL = null; } } else { agentURL = null; } } else { agentURL = null; } return addConstellioProtocol(agentURL, request); } public static String appendAgentURL(String agentURL, String appendedAgentURL) { StringBuilder sb = new StringBuilder(); if (StringUtils.isNotBlank(agentURL)) { sb.append(agentURL); sb.append(URL_SEP); if (appendedAgentURL.startsWith("constellio://")) { appendedAgentURL = StringUtils.removeStart(appendedAgentURL, "constellio://"); } try { appendedAgentURL = URLDecoder.decode(appendedAgentURL, "UTF-8"); appendedAgentURL = StringUtils.substringAfter(appendedAgentURL, "/agentPath"); appendedAgentURL = URLEncoder.encode(appendedAgentURL, "UTF-8"); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } sb.append(appendedAgentURL); return sb.toString(); } public static String getAgentSmbURL(String smbPath) { return getAgentSmbURL(smbPath, null); } public static String getAgentSmbURL(String smbPath, HttpServletRequest request) { String agentSmbURL; if (request == null) { request = VaadinServletService.getCurrentServletRequest(); } String passthroughPath; if (isWindows(request)) { passthroughPath = StringUtils.replace(smbPath, "/", "\\"); passthroughPath = StringUtils.removeStart(passthroughPath, "smb:"); } else { passthroughPath = smbPath; } passthroughPath = UnicodeUtils.unicodeEscape(passthroughPath); String agentBaseURL = getAgentBaseURL(); StringBuffer sb = new StringBuffer(); sb.append(agentBaseURL); sb.append("/passthrough/"); sb.append(passthroughPath); agentSmbURL = sb.toString(); return addConstellioProtocol(agentSmbURL, request); } private static String getResourcePath(RecordVO recordVO, ContentVersionVO contentVersionVO, SessionContext sessionContext) { String resourcePath; ConstellioFactories constellioFactories = ConstellioFactories.getInstance(); ModelLayerFactory modelLayerFactory = constellioFactories.getModelLayerFactory(); RecordServices recordServices = modelLayerFactory.newRecordServices(); Record record = recordServices.getDocumentById(recordVO.getId()); String schemaCode = record.getSchemaCode(); String schemaTypeCode = SchemaUtils.getSchemaTypeCode(schemaCode); String collectionName = record.getCollection(); UserVO currentUserVO = sessionContext.getCurrentUser(); String currentUsername = currentUserVO.getUsername(); String currentUserId = currentUserVO.getId(); String filename = contentVersionVO.getFileName(); String extension = FilenameUtils.getExtension(filename); filename = UnicodeUtils.unicodeEscape(filename); MetadataSchemaTypes types = types(sessionContext); if (UserDocument.SCHEMA_TYPE.equals(schemaTypeCode)) { UserDocument userDocument = new UserDocument(record, types); if (currentUserId.equals(userDocument.getUser())) { StringBuffer sb = new StringBuffer(); sb.append("/"); sb.append(currentUsername); sb.append("/"); sb.append(collectionName); sb.append("/userDocuments"); sb.append("/"); sb.append(userDocument.getId()); sb.append("/"); sb.append(filename); resourcePath = sb.toString(); } else { resourcePath = null; } } else if (Document.SCHEMA_TYPE.equals(schemaTypeCode)) { Document document = new Document(record, types); Content content = document.getContent(); if (content == null) { resourcePath = null; } else if (currentUserId.equals(content.getCheckoutUserId())) { StringBuffer sb = new StringBuffer(); sb.append("/"); sb.append(currentUsername); sb.append("/"); sb.append(collectionName); sb.append("/checkedOutDocuments"); sb.append("/"); sb.append(document.getId()); sb.append("/"); sb.append(filename); resourcePath = sb.toString(); } else { StringBuffer sb = new StringBuffer(); sb.append("/"); sb.append(currentUsername); sb.append("/"); sb.append(collectionName); sb.append("/notCheckedOutDocuments"); sb.append("/"); sb.append(document.getId()); sb.append("/"); sb.append(filename); resourcePath = sb.toString(); } } else { resourcePath = null; } return resourcePath; } private static final MetadataSchemaTypes types(SessionContext sessionContext) { String collectionName = sessionContext.getCurrentCollection(); ModelLayerFactory modelLayerFactory = ConstellioFactories.getInstance().getModelLayerFactory(); MetadataSchemasManager metadataSchemasManager = modelLayerFactory.getMetadataSchemasManager(); return metadataSchemasManager.getSchemaTypes(collectionName); } public static String addConstellioProtocol(String url) { return addConstellioProtocol(url, null); } public static String addConstellioProtocol(String url, HttpServletRequest request) { String agentURL; if (url != null) { if (request == null) { request = VaadinServletService.getCurrentServletRequest(); } String encoding = "UTF-8"; String encodedURL; try { encodedURL = URLEncoder.encode(url, encoding); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } agentURL = "constellio://" + encodedURL; } else { agentURL = null; } return agentURL; } public static String getAgentDownloadURL() { return AGENT_DOWNLOAD_URL; } public static String getAgentVersion() { FoldersLocator foldersLocator = new FoldersLocator(); File resourcesFolder = foldersLocator.getModuleResourcesFolder("rm"); File agentFolder = new File(resourcesFolder, "agent"); File agentVersionFile = new File(agentFolder, "constellio-agent.version"); String version; try { version = FileUtils.readFileToString(agentVersionFile); } catch (IOException e) { throw new RuntimeException(e); } return version; } public static void main(String[] args) throws Exception { URI location = new URI("http://constellio.doculibre.com/#!agentSetup"); String contextPath = "/constellio"; String schemeSpecificPart = location.getSchemeSpecificPart().substring(2); String schemeSpecificPartBeforeContextPath; if (StringUtils.isNotBlank(contextPath)) { if (schemeSpecificPart.indexOf(contextPath) != -1) { schemeSpecificPartBeforeContextPath = StringUtils.substringBeforeLast(schemeSpecificPart, contextPath); } else { contextPath = null; schemeSpecificPartBeforeContextPath = StringUtils.removeEnd(schemeSpecificPart, "/"); } } else { schemeSpecificPartBeforeContextPath = StringUtils.removeEnd(schemeSpecificPart, "/"); } StringBuffer sb = new StringBuffer(); sb.append(location.getScheme()); sb.append("://"); sb.append(schemeSpecificPartBeforeContextPath); if (StringUtils.isNotBlank(contextPath)) { sb.append(contextPath); } sb.append("/agentPath"); System.out.println(sb); } }