mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-21 18:09:20 +00:00
Merged DEV/SWIFT to HEAD
25629: ALF-7069: - changed getNodes to a POST request - beefed up unit tests + some performance tests ALF-7070: - initial checkin, works end-to-end, still work-in-progress - unit + performance tests 25630: ALF-7069: removed files that are no longer needed 25640: Merged BRANCHES\DEV\SOLR to BRANCHES\DEV\SWIFT 25079: SOLR check point: ALF-4259: SOLR Integration 25217: ALF-7068: SOLR 075 Improved cache rebuild performance - delta + query cache warming 25315: ALF-7068: SOLR 075 Improved cache rebuild performance - delta + query cache warming 25577: ALF-7068: SOLR 075 Improved cache rebuild performance - delta + query cache warming 25604: ALF-7068: SOLR 075 Improved cache rebuild performance - delta + query cache warming 25610: ALF-7068: SOLR 075 Improved cache rebuild performance - delta + query cache warming 25651: - enabled OpenCMIS server ticket authentication - added OpenCMIS client API (incomplete) 25667: Merged BRANCHES/DEV/BM to BRANCHES/DEV/SWIFT: 25030: Repo BM Sprint 1 - example using JMeter (WebDAV & CMIS) 25054: Repo BM Sprint 1 - milestone 2 25078: Repo BM sprint 1 - milestone 3 (ALF-6794) 25675: ALF-7068: SOLR 075 Improved cache rebuild performance - delta + query cache warming - fix queries against un-optimized index 25676: Merged BRANCHES/DEV/BM to BRANCHES/DEV/SWIFT: commit mergeinfo 25683: RepoBM: OpenCMIS - use shared libs (from 3rd-party project) - change default url (from ".../alfresco/opencmis-atom" to ".../alfresco/cmisatom") 25767: ALF-7339: SOLR 020 Index track and build from SOLR - Initial hook up point and proto type for config 25787: ALF-7070: - owner, associations, type conversions SOLR Client-side API to call into repository SOLR APIs 25818: added webscripts root object as an entry point to OpenCMIS client sessions (local and remote) 25855: Bug fix: keep CMIS connection manager reference git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@28089 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
<webscript>
|
||||||
|
<shortname>Local test</shortname>
|
||||||
|
<url>/cmissample/local</url>
|
||||||
|
<authentication>user</authentication>
|
||||||
|
</webscript>
|
@@ -0,0 +1,49 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>CMIS Connection</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="${url.context}/css/base.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Repository Info</h1>
|
||||||
|
<table>
|
||||||
|
<tr><td>Id:</td><td>${cmisSession.repositoryInfo.id}</td></tr>
|
||||||
|
<tr><td>Name:</td><td>${cmisSession.repositoryInfo.name}</td></tr>
|
||||||
|
<tr><td>Description:</td><td>${cmisSession.repositoryInfo.description}</td></tr>
|
||||||
|
<tr><td>Vendor:</td><td>${cmisSession.repositoryInfo.vendorName}</td></tr>
|
||||||
|
<tr><td>Product name:</td><td>${cmisSession.repositoryInfo.productName}</td></tr>
|
||||||
|
<tr><td>Product version:</td><td>${cmisSession.repositoryInfo.productVersion}</td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h1>Root folder</h1>
|
||||||
|
Root folder Id: ${cmisSession.rootFolder.id}<br/><br/>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Name</td>
|
||||||
|
<th>Id</td>
|
||||||
|
<th>Type</td>
|
||||||
|
</tr>
|
||||||
|
<#list rootFolderChildren as obj>
|
||||||
|
<tr>
|
||||||
|
<td>${obj.name}</td>
|
||||||
|
<td>${obj.id}</td>
|
||||||
|
<td>${obj.type.id}</td>
|
||||||
|
</tr>
|
||||||
|
</#list>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h1>Base Types</h1>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Name</td>
|
||||||
|
<th>Id</td>
|
||||||
|
</tr>
|
||||||
|
<#list baseTypes as bt>
|
||||||
|
<tr>
|
||||||
|
<td>${bt.displayName}</td>
|
||||||
|
<td>${bt.id}</td>
|
||||||
|
</tr>
|
||||||
|
</#list>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
@@ -0,0 +1,9 @@
|
|||||||
|
// get the local or default remote connection
|
||||||
|
var cmisConnection = cmisclient.getConnection();
|
||||||
|
|
||||||
|
// get CMIS session
|
||||||
|
var cmisSession = cmisConnection.getSession();
|
||||||
|
|
||||||
|
model.cmisSession = cmisSession;
|
||||||
|
model.rootFolderChildren = cmisSession.getRootFolder().getChildren().iterator();
|
||||||
|
model.baseTypes = cmisSession.getTypeChildren(null, false).iterator();
|
@@ -0,0 +1,4 @@
|
|||||||
|
<webscript>
|
||||||
|
<shortname>CMIS servers</shortname>
|
||||||
|
<url>/cmissample/servers</url>
|
||||||
|
</webscript>
|
@@ -0,0 +1,29 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>CMIS Server Defintions</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="${url.context}/css/base.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Configured server definitions</h1>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Name</td>
|
||||||
|
<th>Description</td>
|
||||||
|
<th>Parameters</td>
|
||||||
|
</tr>
|
||||||
|
<#list cmisServers as s>
|
||||||
|
<tr>
|
||||||
|
<td>${s.name}</td>
|
||||||
|
<td>${s.description}</td>
|
||||||
|
<td>
|
||||||
|
<#assign p = s.parameters>
|
||||||
|
<#list p?keys as key>
|
||||||
|
<code>${key} = ${p[key]}</code><br/>
|
||||||
|
</#list>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</#list>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
@@ -0,0 +1,2 @@
|
|||||||
|
// get all configured CMIS servers
|
||||||
|
model.cmisServers = cmisclient.getServerDefinitions();
|
@@ -0,0 +1,9 @@
|
|||||||
|
<webscript>
|
||||||
|
<shortname>Get node property content as text</shortname>
|
||||||
|
<description>Get the content for the node property as text.</description>
|
||||||
|
<url>/api/solr/{nodeId}/{propertyQName?}/textContent</url>
|
||||||
|
<format default="json">argument</format>
|
||||||
|
<authentication>admin</authentication>
|
||||||
|
<transaction allow="readonly">required</transaction>
|
||||||
|
<lifecycle>internal</lifecycle>
|
||||||
|
</webscript>
|
@@ -1,8 +1,9 @@
|
|||||||
<webscript>
|
<webscript>
|
||||||
<shortname>Get the nodes in the given transactions</shortname>
|
<shortname>Get the nodes in the given transactions</shortname>
|
||||||
<description>Get the nodes updated/deleted in the given transactions.</description>
|
<description>Get the nodes updated/deleted in the given transactions.</description>
|
||||||
<url>/api/solr/nodes?txnIds={txnIds}&{fromNodeId?}&{toNodeId?}&{count?}</url>
|
<url>/api/solr/nodes</url>
|
||||||
<format default="json">argument</format>
|
<format default="json">argument</format>
|
||||||
<authentication>admin</authentication>
|
<authentication>admin</authentication>
|
||||||
<transaction allow="readonly">required</transaction>
|
<transaction allow="readonly">required</transaction>
|
||||||
|
<lifecycle>internal</lifecycle>
|
||||||
</webscript>
|
</webscript>
|
@@ -6,6 +6,5 @@
|
|||||||
<@solrLib.nodeJSON node=node/>
|
<@solrLib.nodeJSON node=node/>
|
||||||
<#if node_has_next>,</#if>
|
<#if node_has_next>,</#if>
|
||||||
</#list>
|
</#list>
|
||||||
],
|
]
|
||||||
"count": ${count}
|
|
||||||
}
|
}
|
@@ -0,0 +1,9 @@
|
|||||||
|
<webscript>
|
||||||
|
<shortname>Get the metadata for the specified nodes</shortname>
|
||||||
|
<description>Get the metadata for the specified nodes.</description>
|
||||||
|
<url>/api/solr/metadata</url>
|
||||||
|
<format default="json">argument</format>
|
||||||
|
<authentication>admin</authentication>
|
||||||
|
<transaction allow="readonly">required</transaction>
|
||||||
|
<lifecycle>internal</lifecycle>
|
||||||
|
</webscript>
|
@@ -0,0 +1,9 @@
|
|||||||
|
<#import "solr.lib.ftl" as solrLib/>
|
||||||
|
{
|
||||||
|
"nodes" :
|
||||||
|
[
|
||||||
|
<#list nodes as nodeMetaData>
|
||||||
|
<@solrLib.nodeMetaDataJSON nodeMetaData=nodeMetaData filter=filter/><#if nodeMetaData_has_next>,</#if>
|
||||||
|
</#list>
|
||||||
|
]
|
||||||
|
}
|
@@ -1,8 +1,9 @@
|
|||||||
<webscript>
|
<webscript>
|
||||||
<shortname>Get transactions</shortname>
|
<shortname>Get transactions</shortname>
|
||||||
<description>Get the transactions from the given commit time.</description>
|
<description>Get the transactions from the given commit time.</description>
|
||||||
<url>/api/solr/transactions?fromCommitTime={fromCommitTime}</url>
|
<url>/api/solr/transactions?fromTxnId={fromTxnId?}&fromCommitTime={fromCommitTime?}&maxResults={maxResults?}</url>
|
||||||
<format default="json">argument</format>
|
<format default="json">argument</format>
|
||||||
<authentication>admin</authentication>
|
<authentication>admin</authentication>
|
||||||
<transaction allow="readonly">required</transaction>
|
<transaction allow="readonly">required</transaction>
|
||||||
|
<lifecycle>internal</lifecycle>
|
||||||
</webscript>
|
</webscript>
|
@@ -1,16 +1,67 @@
|
|||||||
<#macro transactionJSON txn>
|
<#macro transactionJSON txn>
|
||||||
{
|
{
|
||||||
"id": "${txn.id?c}",
|
"id": ${txn.id?c},
|
||||||
"commitTimeMs": "${txn.commitTimeMs?c}",
|
"commitTimeMs": ${txn.commitTimeMs?c},
|
||||||
"updates": "${txn.updates?c}",
|
"updates": ${txn.updates?c},
|
||||||
"deletes": "${txn.deletes?c}"
|
"deletes": ${txn.deletes?c}
|
||||||
}
|
}
|
||||||
</#macro>
|
</#macro>
|
||||||
|
|
||||||
<#macro nodeJSON node>
|
<#macro nodeJSON node>
|
||||||
{
|
{
|
||||||
"nodeID": "${node.id?c}",
|
"id": ${node.id?c},
|
||||||
"txnID": "${node.transaction.id?c}",
|
"txnId": ${node.transaction.id?c},
|
||||||
"deleted": "${node.deleted?string}"
|
"status": "<#if node.deleted>d<#else>u</#if>"
|
||||||
}
|
}
|
||||||
</#macro>
|
</#macro>
|
||||||
|
|
||||||
|
<#--
|
||||||
|
TODO property values: string, number, date (at the moment all output as string)
|
||||||
|
-->
|
||||||
|
<#macro nodeMetaDataJSON nodeMetaData filter>
|
||||||
|
{
|
||||||
|
"id": ${nodeMetaData.nodeId?c},
|
||||||
|
"nodeRef": <#if filter.includeNodeRef??>"${nodeMetaData.nodeRef.toString()}",</#if>
|
||||||
|
"type": <#if filter.includeType??><@qNameJSON qName=nodeMetaData.nodeType/>,</#if>
|
||||||
|
"aclId": <#if filter.includeAclId??><#if nodeMetaData.aclId??>${nodeMetaData.aclId?c}<#else>null</#if>,</#if>
|
||||||
|
<#if filter.includeProperties??>
|
||||||
|
"properties": {
|
||||||
|
<#list nodeMetaData.properties?keys as propQName>
|
||||||
|
<@qNameJSON qName=propQName/>: ${nodeMetaData.properties[propQName]}<#if propQName_has_next>,</#if>
|
||||||
|
</#list>
|
||||||
|
},
|
||||||
|
</#if>
|
||||||
|
<#if filter.includeAspects??>
|
||||||
|
"aspects": [
|
||||||
|
<#list nodeMetaData.aspects as aspectQName>
|
||||||
|
<@nodeAspectJSON aspectQName=aspectQName indent=""/><#if aspectQName_has_next>,</#if>
|
||||||
|
</#list>
|
||||||
|
],
|
||||||
|
</#if>
|
||||||
|
<#if filter.includePaths??>
|
||||||
|
"paths": [
|
||||||
|
<#list nodeMetaData.paths as path>
|
||||||
|
<@pathJSON path=path indent=""/><#if path_has_next>,</#if>
|
||||||
|
</#list>
|
||||||
|
]
|
||||||
|
</#if>
|
||||||
|
}
|
||||||
|
</#macro>
|
||||||
|
|
||||||
|
<#macro pathJSON path indent="">
|
||||||
|
${indent}"${path.toString()}"
|
||||||
|
</#macro>
|
||||||
|
|
||||||
|
<#macro qNameJSON qName indent="">
|
||||||
|
${indent}"${jsonUtils.encodeJSONString(shortQName(qName))}"
|
||||||
|
</#macro>
|
||||||
|
|
||||||
|
<#macro nodePropertyJSON propQName propValue>
|
||||||
|
<@qNameJSON qName=propQName/>: <#if propValue??>"propValue"<#else>null</#if>
|
||||||
|
</#macro>
|
||||||
|
|
||||||
|
<#macro nodeAspectJSON aspectQName indent="">
|
||||||
|
${indent}<@qNameJSON qName=aspectQName/>
|
||||||
|
</#macro>
|
||||||
|
|
||||||
|
|
||||||
|
@@ -142,6 +142,9 @@
|
|||||||
<entry key="paging">
|
<entry key="paging">
|
||||||
<ref bean="webscripts.js.paging"/>
|
<ref bean="webscripts.js.paging"/>
|
||||||
</entry>
|
</entry>
|
||||||
|
<entry key="cmisclient">
|
||||||
|
<ref bean="webscripts.js.cmis.client" />
|
||||||
|
</entry>
|
||||||
</map>
|
</map>
|
||||||
</property>
|
</property>
|
||||||
<property name="templateObjects">
|
<property name="templateObjects">
|
||||||
@@ -362,6 +365,48 @@
|
|||||||
<!-- CMIS Query -->
|
<!-- CMIS Query -->
|
||||||
<bean id="webscript.org.alfresco.cmis.query.get" class="org.alfresco.repo.cmis.rest.CMISQueryWebScript" parent="webscript" />
|
<bean id="webscript.org.alfresco.cmis.query.get" class="org.alfresco.repo.cmis.rest.CMISQueryWebScript" parent="webscript" />
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
<!-- CMIS Client -->
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
<bean id="webscripts.js.cmis.client" class="org.alfresco.repo.cmis.client.CMISLocalConnectionManagerImpl">
|
||||||
|
<property name="authenticationService" ref="AuthenticationService" />
|
||||||
|
<property name="cmisConnector" ref="CMISConnector" />
|
||||||
|
<property name="servers">
|
||||||
|
<list>
|
||||||
|
<map>
|
||||||
|
<entry key="name" value="demo"/>
|
||||||
|
<entry key="description" value="cmis.alfresco.com"/>
|
||||||
|
<entry key="org.apache.chemistry.opencmis.binding.spi.type" value="atompub"/>
|
||||||
|
<entry key="org.apache.chemistry.opencmis.binding.atompub.url" value="http://cmis.alfresco.com/service/cmis"/>
|
||||||
|
</map>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<bean id="webscripts.js.cmis.client" class="org.alfresco.repo.cmis.client.CMISRemoteConnectionManagerImpl">
|
||||||
|
<property name="authenticationService" ref="AuthenticationService" />
|
||||||
|
<property name="defaultServer">
|
||||||
|
<map>
|
||||||
|
<entry key="name" value="default"/>
|
||||||
|
<entry key="description" value="Default server"/>
|
||||||
|
<entry key="org.apache.chemistry.opencmis.binding.spi.type" value="atompub"/>
|
||||||
|
<entry key="org.apache.chemistry.opencmis.binding.atompub.url" value="http://<host>/service/cmis"/>
|
||||||
|
</map>
|
||||||
|
</property>
|
||||||
|
<property name="servers">
|
||||||
|
<list>
|
||||||
|
<map>
|
||||||
|
<entry key="name" value="demo"/>
|
||||||
|
<entry key="description" value="cmis.alfresco.com"/>
|
||||||
|
<entry key="org.apache.chemistry.opencmis.binding.spi.type" value="atompub"/>
|
||||||
|
<entry key="org.apache.chemistry.opencmis.binding.atompub.url" value="http://cmis.alfresco.com/service/cmis"/>
|
||||||
|
</map>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
-->
|
||||||
|
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<!-- API Beans -->
|
<!-- API Beans -->
|
||||||
@@ -1181,16 +1226,35 @@
|
|||||||
<!-- -->
|
<!-- -->
|
||||||
<!-- -->
|
<!-- -->
|
||||||
|
|
||||||
|
<bean id="solrSerializer" class="org.alfresco.util.SOLRSerializer" init-method="init">
|
||||||
|
<property name="dictionaryService" ref="dictionaryService"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
<bean id="webscript.org.alfresco.repository.solr.getTransactions.get"
|
<bean id="webscript.org.alfresco.repository.solr.getTransactions.get"
|
||||||
class="org.alfresco.repo.web.scripts.solr.GetTransactions"
|
class="org.alfresco.repo.web.scripts.solr.GetTransactions"
|
||||||
parent="webscript">
|
parent="webscript">
|
||||||
<property name="solrDAO" ref="solrDAO"/>
|
<property name="solrDAO" ref="solrDAO"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="webscript.org.alfresco.repository.solr.getNodes.get"
|
<bean id="webscript.org.alfresco.repository.solr.getNodes.post"
|
||||||
class="org.alfresco.repo.web.scripts.solr.GetNodes"
|
class="org.alfresco.repo.web.scripts.solr.GetNodes"
|
||||||
parent="webscript">
|
parent="webscript">
|
||||||
<property name="solrDAO" ref="solrDAO"/>
|
<property name="solrDAO" ref="solrDAO"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean id="webscript.org.alfresco.repository.solr.getNodesMetaData.post"
|
||||||
|
class="org.alfresco.repo.web.scripts.solr.GetNodesMetaData"
|
||||||
|
parent="webscript">
|
||||||
|
<property name="solrDAO" ref="solrDAO"/>
|
||||||
|
<property name="solrSerializer" ref="solrSerializer"/>
|
||||||
|
</bean>
|
||||||
|
<!--
|
||||||
|
<bean id="webscript.org.alfresco.repository.solr.getNodeContent.get"
|
||||||
|
class="org.alfresco.repo.web.scripts.solr.GetNodeContent"
|
||||||
|
parent="webscript">
|
||||||
|
<property name="contentService" ref="contentService"/>
|
||||||
|
<property name="nodeService" ref="nodeService"/>
|
||||||
|
<property name="nodeDAO" ref="nodeDAO"/>
|
||||||
|
</bean>
|
||||||
|
-->
|
||||||
</beans>
|
</beans>
|
||||||
|
@@ -0,0 +1,397 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2011 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.cmis.client;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
|
||||||
|
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||||
|
import org.apache.chemistry.opencmis.client.api.Repository;
|
||||||
|
import org.apache.chemistry.opencmis.client.api.Session;
|
||||||
|
import org.apache.chemistry.opencmis.client.api.SessionFactory;
|
||||||
|
import org.apache.chemistry.opencmis.client.runtime.SessionFactoryImpl;
|
||||||
|
import org.apache.chemistry.opencmis.commons.SessionParameter;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
public abstract class AbstractCMISConnectionManagerImpl implements CMISConnectionManager, InitializingBean
|
||||||
|
{
|
||||||
|
public static final String SERVER_NAME = "name";
|
||||||
|
public static final String SERVER_DESCRIPTION = "description";
|
||||||
|
public static final String LOCAL_CONNECTION_ID = "local";
|
||||||
|
public static final char RESERVED_ID_CHAR = '$';
|
||||||
|
|
||||||
|
protected AuthenticationService authenticationService;
|
||||||
|
|
||||||
|
protected SessionFactory sessionFactory;
|
||||||
|
|
||||||
|
protected LinkedHashMap<String, CMISConnection> sharedConnections;
|
||||||
|
protected LinkedHashMap<String, CMISConnection> userConnections;
|
||||||
|
protected int userConnectionsCapacity = 1000;
|
||||||
|
protected int sharedConnectionsCapacity = 1000;
|
||||||
|
|
||||||
|
protected Map<String, CMISServer> servers;
|
||||||
|
|
||||||
|
protected ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
||||||
|
|
||||||
|
public void setAuthenticationService(AuthenticationService authenticationService)
|
||||||
|
{
|
||||||
|
this.authenticationService = authenticationService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserConnectionsCapacity(int userConnectionsCapacity)
|
||||||
|
{
|
||||||
|
this.userConnectionsCapacity = userConnectionsCapacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSharedConnectionsCapacity(int sharedConnectionsCapacity)
|
||||||
|
{
|
||||||
|
this.sharedConnectionsCapacity = sharedConnectionsCapacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServers(List<Map<String, String>> serverList)
|
||||||
|
{
|
||||||
|
servers = new HashMap<String, CMISServer>();
|
||||||
|
|
||||||
|
for (Map<String, String> serverData : serverList)
|
||||||
|
{
|
||||||
|
CMISServer server = createServerDefinition(serverData);
|
||||||
|
if (server != null)
|
||||||
|
{
|
||||||
|
servers.put(server.getName(), server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception
|
||||||
|
{
|
||||||
|
lock.writeLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
sessionFactory = SessionFactoryImpl.newInstance();
|
||||||
|
|
||||||
|
sharedConnections = new LinkedHashMap<String, CMISConnection>(sharedConnectionsCapacity,
|
||||||
|
(int) Math.ceil(sharedConnectionsCapacity / 0.75) + 1, true)
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 1;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean removeEldestEntry(Map.Entry<String, CMISConnection> eldest)
|
||||||
|
{
|
||||||
|
return size() > sharedConnectionsCapacity;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
userConnections = new LinkedHashMap<String, CMISConnection>(userConnectionsCapacity,
|
||||||
|
(int) Math.ceil(userConnectionsCapacity / 0.75) + 1, true)
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 1;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean removeEldestEntry(Map.Entry<String, CMISConnection> eldest)
|
||||||
|
{
|
||||||
|
return size() > userConnectionsCapacity;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} finally
|
||||||
|
{
|
||||||
|
lock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CMISConnection createUserConnection(CMISServer server, String connectionId)
|
||||||
|
{
|
||||||
|
String currentUser = authenticationService.getCurrentUserName();
|
||||||
|
if (currentUser == null)
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("No current user!");
|
||||||
|
}
|
||||||
|
|
||||||
|
String userConnectionId = createUserConnectionId(currentUser, connectionId);
|
||||||
|
|
||||||
|
CMISConnection connection;
|
||||||
|
|
||||||
|
lock.writeLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (userConnections.containsKey(userConnectionId))
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("Connection id is already in use!");
|
||||||
|
}
|
||||||
|
|
||||||
|
connection = createConnection(server, userConnectionId);
|
||||||
|
|
||||||
|
userConnections.put(userConnectionId, connection);
|
||||||
|
} finally
|
||||||
|
{
|
||||||
|
lock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String createUserConnectionId(String username, String connectionId)
|
||||||
|
{
|
||||||
|
return connectionId + RESERVED_ID_CHAR + username;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CMISConnection createSharedConnection(CMISServer server, String connectionId)
|
||||||
|
{
|
||||||
|
CMISConnection connection;
|
||||||
|
|
||||||
|
lock.writeLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (sharedConnections.containsKey(connectionId))
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("Connection id is already in use!");
|
||||||
|
}
|
||||||
|
|
||||||
|
connection = createConnection(server, connectionId);
|
||||||
|
|
||||||
|
sharedConnections.put(connection.getId(), connection);
|
||||||
|
} finally
|
||||||
|
{
|
||||||
|
lock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CMISConnection createConnection(CMISServer server, String connectionId)
|
||||||
|
{
|
||||||
|
if (connectionId == null || connectionId.length() == 0 || connectionId.indexOf(RESERVED_ID_CHAR) > -1)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Invalid connection id!");
|
||||||
|
}
|
||||||
|
|
||||||
|
Session session = createSession(server.getParameters());
|
||||||
|
String username = server.getParameters().get(SessionParameter.USER);
|
||||||
|
|
||||||
|
return new CMISConnectionImpl(this, connectionId, session, server, username, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public abstract CMISConnection getConnection();
|
||||||
|
|
||||||
|
public Collection<CMISConnection> getUserConnections()
|
||||||
|
{
|
||||||
|
String currentUser = authenticationService.getCurrentUserName();
|
||||||
|
if (currentUser == null)
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("No current user!");
|
||||||
|
}
|
||||||
|
|
||||||
|
lock.writeLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
List<CMISConnection> result = new ArrayList<CMISConnection>();
|
||||||
|
|
||||||
|
for (CMISConnection conn : userConnections.values())
|
||||||
|
{
|
||||||
|
int idx = conn.getId().indexOf(RESERVED_ID_CHAR);
|
||||||
|
if (idx > -1)
|
||||||
|
{
|
||||||
|
if (currentUser.equals(conn.getId().substring(idx + 1)))
|
||||||
|
{
|
||||||
|
result.add(conn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Collections.unmodifiableList(result);
|
||||||
|
} finally
|
||||||
|
{
|
||||||
|
lock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public CMISConnection getUserConnections(String connectionId)
|
||||||
|
{
|
||||||
|
String currentUser = authenticationService.getCurrentUserName();
|
||||||
|
if (currentUser == null)
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("No current user!");
|
||||||
|
}
|
||||||
|
|
||||||
|
lock.writeLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String userConnectionId = createUserConnectionId(currentUser, connectionId);
|
||||||
|
return userConnections.get(userConnectionId);
|
||||||
|
} finally
|
||||||
|
{
|
||||||
|
lock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<CMISConnection> getSharedConnections()
|
||||||
|
{
|
||||||
|
lock.writeLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return Collections.unmodifiableCollection(sharedConnections.values());
|
||||||
|
} finally
|
||||||
|
{
|
||||||
|
lock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public CMISConnection getSharedConnection(String connectionId)
|
||||||
|
{
|
||||||
|
lock.writeLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return sharedConnections.get(connectionId);
|
||||||
|
} finally
|
||||||
|
{
|
||||||
|
lock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeConnection(CMISConnection connection)
|
||||||
|
{
|
||||||
|
if (connection == null || connection.getId() == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lock.writeLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (connection.isLocal())
|
||||||
|
{
|
||||||
|
userConnections.remove(LOCAL_CONNECTION_ID);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
int idx = connection.getId().indexOf(RESERVED_ID_CHAR);
|
||||||
|
if (idx == -1)
|
||||||
|
{
|
||||||
|
sharedConnections.remove(connection.getId());
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
userConnections.remove(connection.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally
|
||||||
|
{
|
||||||
|
lock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Session createSession(Map<String, String> parameters)
|
||||||
|
{
|
||||||
|
if (parameters.containsKey(SessionParameter.REPOSITORY_ID))
|
||||||
|
{
|
||||||
|
return sessionFactory.createSession(new HashMap<String, String>(parameters));
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
return sessionFactory.getRepositories(new HashMap<String, String>(parameters)).get(0).createSession();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<CMISServer> getServerDefinitions()
|
||||||
|
{
|
||||||
|
return servers == null ? null : servers.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CMISServer getServerDefinition(String serverName)
|
||||||
|
{
|
||||||
|
return servers == null ? null : servers.get(serverName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CMISServer createServerDefinition(String serverName, Map<String, String> parameters)
|
||||||
|
{
|
||||||
|
return new CMISServerImpl(serverName, null, parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CMISServer createServerDefinition(CMISServer server, String username, String password)
|
||||||
|
{
|
||||||
|
if (server == null)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Server must be set!");
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, String> parameters = new HashMap<String, String>(server.getParameters());
|
||||||
|
parameters.put(SessionParameter.USER, username);
|
||||||
|
parameters.put(SessionParameter.PASSWORD, password);
|
||||||
|
|
||||||
|
return new CMISServerImpl(server.getName(), server.getDescription(), parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CMISServer createServerDefinition(CMISServer server, String username, String password, String repositoryId)
|
||||||
|
{
|
||||||
|
if (server == null)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Server must be set!");
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, String> parameters = new HashMap<String, String>(server.getParameters());
|
||||||
|
parameters.put(SessionParameter.USER, username);
|
||||||
|
parameters.put(SessionParameter.PASSWORD, password);
|
||||||
|
parameters.put(SessionParameter.REPOSITORY_ID, repositoryId);
|
||||||
|
|
||||||
|
return new CMISServerImpl(server.getName(), server.getDescription(), parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CMISServer createServerDefinition(Map<String, String> parameters)
|
||||||
|
{
|
||||||
|
if (parameters == null)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Parameters must be set!");
|
||||||
|
}
|
||||||
|
|
||||||
|
String name = parameters.get(SERVER_NAME);
|
||||||
|
parameters.remove(SERVER_NAME);
|
||||||
|
|
||||||
|
String description = parameters.get(SERVER_DESCRIPTION);
|
||||||
|
parameters.remove(SERVER_DESCRIPTION);
|
||||||
|
|
||||||
|
if (name != null)
|
||||||
|
{
|
||||||
|
return new CMISServerImpl(name, description, parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Repository> getRepositories(CMISServer server)
|
||||||
|
{
|
||||||
|
if (server == null)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Server must be set!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return sessionFactory.getRepositories(new HashMap<String, String>(server.getParameters()));
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2011 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.cmis.client;
|
||||||
|
|
||||||
|
import org.apache.chemistry.opencmis.client.api.Session;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a CMIS connection.
|
||||||
|
*/
|
||||||
|
public interface CMISConnection
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Gets connection id.
|
||||||
|
*
|
||||||
|
* @return connection id
|
||||||
|
*/
|
||||||
|
String getId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets OpenCMIS Session.
|
||||||
|
*
|
||||||
|
* @return OpenCMIS session
|
||||||
|
*/
|
||||||
|
Session getSession();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the CMIS Server.
|
||||||
|
*
|
||||||
|
* @return CMIS Server
|
||||||
|
*/
|
||||||
|
CMISServer getServer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the user name.
|
||||||
|
*
|
||||||
|
* @return user name
|
||||||
|
*/
|
||||||
|
String getUserName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if the connection is a local or a remote connection.
|
||||||
|
*/
|
||||||
|
boolean isLocal();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Releases the CMIS session and removes the connection from connection
|
||||||
|
* manager.
|
||||||
|
*/
|
||||||
|
void close();
|
||||||
|
}
|
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2011 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.cmis.client;
|
||||||
|
|
||||||
|
public class CMISConnectionCache
|
||||||
|
{
|
||||||
|
private int capacity;
|
||||||
|
|
||||||
|
public CMISConnectionCache(int capacity)
|
||||||
|
{
|
||||||
|
this.capacity = capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(CMISConnection connection)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove(CMISConnection connection)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2011 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.cmis.client;
|
||||||
|
|
||||||
|
import org.apache.chemistry.opencmis.client.api.Session;
|
||||||
|
|
||||||
|
public class CMISConnectionImpl implements CMISConnection
|
||||||
|
{
|
||||||
|
private AbstractCMISConnectionManagerImpl connectionManager;
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private Session session;
|
||||||
|
private CMISServer server;
|
||||||
|
private String username;
|
||||||
|
private boolean isLocal;
|
||||||
|
|
||||||
|
public CMISConnectionImpl(AbstractCMISConnectionManagerImpl connectionManager, String id, Session session,
|
||||||
|
CMISServer server, String username, boolean isLocal)
|
||||||
|
{
|
||||||
|
if (connectionManager == null)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Connection Manager must be set!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id == null)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Id must be set!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session == null)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Session must be set!");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.connectionManager = connectionManager;
|
||||||
|
this.id = id;
|
||||||
|
this.session = session;
|
||||||
|
this.server = server;
|
||||||
|
this.username = username;
|
||||||
|
this.isLocal = isLocal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId()
|
||||||
|
{
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Session getSession()
|
||||||
|
{
|
||||||
|
return session;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CMISServer getServer()
|
||||||
|
{
|
||||||
|
return server;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUserName()
|
||||||
|
{
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLocal()
|
||||||
|
{
|
||||||
|
return isLocal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close()
|
||||||
|
{
|
||||||
|
connectionManager.removeConnection(this);
|
||||||
|
session = null;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2011 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.cmis.client;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.chemistry.opencmis.client.api.Repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages all CMIS client connections.
|
||||||
|
*/
|
||||||
|
public interface CMISConnectionManager
|
||||||
|
{
|
||||||
|
// --- connections ---
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new connection that is only visible to the current user.
|
||||||
|
*/
|
||||||
|
CMISConnection createUserConnection(CMISServer server, String connectionId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new connection that is visible to all users.
|
||||||
|
*/
|
||||||
|
CMISConnection createSharedConnection(CMISServer server, String connectionId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets or creates a connection to the local server or a default server.
|
||||||
|
*/
|
||||||
|
CMISConnection getConnection();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all user connections.
|
||||||
|
*/
|
||||||
|
Collection<CMISConnection> getUserConnections();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a specific user connection or <code>null</code> if the connection
|
||||||
|
* id is unknown.
|
||||||
|
*/
|
||||||
|
CMISConnection getUserConnections(String connectionId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all shared connections.
|
||||||
|
*/
|
||||||
|
Collection<CMISConnection> getSharedConnections();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a specific shared connection or <code>null</code> if the
|
||||||
|
* connection id is unknown.
|
||||||
|
*/
|
||||||
|
CMISConnection getSharedConnection(String connectionId);
|
||||||
|
|
||||||
|
// --- servers ---
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all configured server definitions.
|
||||||
|
*/
|
||||||
|
Collection<CMISServer> getServerDefinitions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a server definitions by name.
|
||||||
|
*/
|
||||||
|
CMISServer getServerDefinition(String serverName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new server definition.
|
||||||
|
*/
|
||||||
|
CMISServer createServerDefinition(String serverName, Map<String, String> parameters);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new server definition from a template.
|
||||||
|
*/
|
||||||
|
CMISServer createServerDefinition(CMISServer server, String username, String password);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new server definition from a template.
|
||||||
|
*/
|
||||||
|
CMISServer createServerDefinition(CMISServer server, String username, String password, String repositoryId);
|
||||||
|
|
||||||
|
// --- repositories ---
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all repositories available at this server.
|
||||||
|
*/
|
||||||
|
List<Repository> getRepositories(CMISServer server);
|
||||||
|
}
|
@@ -0,0 +1,394 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2011 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.cmis.client;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
|
||||||
|
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||||
|
import org.apache.chemistry.opencmis.client.api.Repository;
|
||||||
|
import org.apache.chemistry.opencmis.client.api.Session;
|
||||||
|
import org.apache.chemistry.opencmis.client.api.SessionFactory;
|
||||||
|
import org.apache.chemistry.opencmis.client.runtime.SessionFactoryImpl;
|
||||||
|
import org.apache.chemistry.opencmis.commons.SessionParameter;
|
||||||
|
import org.apache.chemistry.opencmis.commons.enums.BindingType;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
public class CMISConnectionManagerImpl implements CMISConnectionManager, InitializingBean
|
||||||
|
{
|
||||||
|
public static final String SERVER_NAME = "name";
|
||||||
|
public static final String SERVER_DESCRIPTION = "description";
|
||||||
|
public static final String LOCAL_CONNECTION_ID = "local";
|
||||||
|
public static final char RESERVED_ID_CHAR = '$';
|
||||||
|
|
||||||
|
private AuthenticationService authenticationService;
|
||||||
|
|
||||||
|
private SessionFactory sessionFactory;
|
||||||
|
|
||||||
|
private LinkedHashMap<String, CMISConnection> sharedConnections;
|
||||||
|
private LinkedHashMap<String, CMISConnection> userConnections;
|
||||||
|
private int userConnectionsCapacity = 1000;
|
||||||
|
private int sharedConnectionsCapacity = 1000;
|
||||||
|
|
||||||
|
private Map<String, CMISServer> servers;
|
||||||
|
|
||||||
|
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
||||||
|
|
||||||
|
public CMISConnectionManagerImpl()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthenticationService(AuthenticationService authenticationService)
|
||||||
|
{
|
||||||
|
this.authenticationService = authenticationService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServers(List<Map<String, String>> serverList)
|
||||||
|
{
|
||||||
|
servers = new HashMap<String, CMISServer>();
|
||||||
|
|
||||||
|
for (Map<String, String> serverData : serverList)
|
||||||
|
{
|
||||||
|
String name = serverData.get(SERVER_NAME);
|
||||||
|
serverData.remove(SERVER_NAME);
|
||||||
|
|
||||||
|
String description = serverData.get(SERVER_DESCRIPTION);
|
||||||
|
serverData.remove(SERVER_DESCRIPTION);
|
||||||
|
|
||||||
|
if (name != null)
|
||||||
|
{
|
||||||
|
CMISServer server = new CMISServerImpl(name, description, serverData);
|
||||||
|
servers.put(server.getName(), server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception
|
||||||
|
{
|
||||||
|
lock.writeLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
sessionFactory = SessionFactoryImpl.newInstance();
|
||||||
|
|
||||||
|
sharedConnections = new LinkedHashMap<String, CMISConnection>(sharedConnectionsCapacity,
|
||||||
|
(int) Math.ceil(sharedConnectionsCapacity / 0.75) + 1, true)
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 1;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean removeEldestEntry(Map.Entry<String, CMISConnection> eldest)
|
||||||
|
{
|
||||||
|
return size() > sharedConnectionsCapacity;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
userConnections = new LinkedHashMap<String, CMISConnection>(userConnectionsCapacity,
|
||||||
|
(int) Math.ceil(userConnectionsCapacity / 0.75) + 1, true)
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 1;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean removeEldestEntry(Map.Entry<String, CMISConnection> eldest)
|
||||||
|
{
|
||||||
|
return size() > userConnectionsCapacity;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} finally
|
||||||
|
{
|
||||||
|
lock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CMISConnection createUserConnection(CMISServer server, String connectionId)
|
||||||
|
{
|
||||||
|
String currentUser = authenticationService.getCurrentUserName();
|
||||||
|
if (currentUser == null)
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("No current user!");
|
||||||
|
}
|
||||||
|
|
||||||
|
String userConnectionId = createUserConnectionId(currentUser, connectionId);
|
||||||
|
|
||||||
|
CMISConnection connection;
|
||||||
|
|
||||||
|
lock.writeLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (userConnections.containsKey(userConnectionId))
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("Connection id is already in use!");
|
||||||
|
}
|
||||||
|
|
||||||
|
connection = createConnection(server, userConnectionId);
|
||||||
|
|
||||||
|
userConnections.put(connection.getId(), connection);
|
||||||
|
} finally
|
||||||
|
{
|
||||||
|
lock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String createUserConnectionId(String username, String connectionId)
|
||||||
|
{
|
||||||
|
return connectionId + RESERVED_ID_CHAR + username;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CMISConnection createSharedConnection(CMISServer server, String connectionId)
|
||||||
|
{
|
||||||
|
CMISConnection connection;
|
||||||
|
|
||||||
|
lock.writeLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (sharedConnections.containsKey(connectionId))
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("Connection id is already in use!");
|
||||||
|
}
|
||||||
|
|
||||||
|
connection = createConnection(server, connectionId);
|
||||||
|
|
||||||
|
sharedConnections.put(connection.getId(), connection);
|
||||||
|
} finally
|
||||||
|
{
|
||||||
|
lock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CMISConnection createConnection(CMISServer server, String connectionId)
|
||||||
|
{
|
||||||
|
if (connectionId == null || connectionId.length() == 0 || connectionId.indexOf(RESERVED_ID_CHAR) > -1)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Invalid connection id!");
|
||||||
|
}
|
||||||
|
|
||||||
|
Session session = sessionFactory.createSession(server.getParameters());
|
||||||
|
String username = server.getParameters().get(SessionParameter.USER);
|
||||||
|
|
||||||
|
return new CMISConnectionImpl(this, connectionId, session, server, username, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CMISConnection getLocalConnection()
|
||||||
|
{
|
||||||
|
CMISConnection connection = getUserConnections(LOCAL_CONNECTION_ID);
|
||||||
|
if (connection != null)
|
||||||
|
{
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, String> parameters = new HashMap<String, String>();
|
||||||
|
parameters.put(SessionParameter.BINDING_TYPE, BindingType.LOCAL.value());
|
||||||
|
// ToDo: add factory
|
||||||
|
|
||||||
|
CMISServer server = createServerDefinition("local", parameters);
|
||||||
|
|
||||||
|
Session session = sessionFactory.createSession(server.getParameters());
|
||||||
|
|
||||||
|
connection = new CMISConnectionImpl(this, LOCAL_CONNECTION_ID, session, server, null, true);
|
||||||
|
|
||||||
|
lock.writeLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
userConnections.put(connection.getId(), connection);
|
||||||
|
} finally
|
||||||
|
{
|
||||||
|
lock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<CMISConnection> getUserConnections()
|
||||||
|
{
|
||||||
|
String currentUser = authenticationService.getCurrentUserName();
|
||||||
|
if (currentUser == null)
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("No current user!");
|
||||||
|
}
|
||||||
|
|
||||||
|
lock.writeLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
List<CMISConnection> result = new ArrayList<CMISConnection>();
|
||||||
|
|
||||||
|
for (CMISConnection conn : userConnections.values())
|
||||||
|
{
|
||||||
|
int idx = conn.getId().indexOf(RESERVED_ID_CHAR);
|
||||||
|
if (idx > -1)
|
||||||
|
{
|
||||||
|
if (currentUser.equals(conn.getId().substring(idx + 1)))
|
||||||
|
{
|
||||||
|
result.add(conn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Collections.unmodifiableList(result);
|
||||||
|
} finally
|
||||||
|
{
|
||||||
|
lock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public CMISConnection getUserConnections(String connectionId)
|
||||||
|
{
|
||||||
|
String currentUser = authenticationService.getCurrentUserName();
|
||||||
|
if (currentUser == null)
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("No current user!");
|
||||||
|
}
|
||||||
|
|
||||||
|
lock.writeLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String userConnectionId = createUserConnectionId(currentUser, connectionId);
|
||||||
|
return userConnections.get(userConnectionId);
|
||||||
|
} finally
|
||||||
|
{
|
||||||
|
lock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<CMISConnection> getSharedConnections()
|
||||||
|
{
|
||||||
|
lock.writeLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return Collections.unmodifiableCollection(sharedConnections.values());
|
||||||
|
} finally
|
||||||
|
{
|
||||||
|
lock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public CMISConnection getSharedConnection(String connectionId)
|
||||||
|
{
|
||||||
|
lock.writeLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return sharedConnections.get(connectionId);
|
||||||
|
} finally
|
||||||
|
{
|
||||||
|
lock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeConnection(CMISConnection connection)
|
||||||
|
{
|
||||||
|
if (connection == null || connection.getId() == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lock.writeLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (connection.isLocal())
|
||||||
|
{
|
||||||
|
userConnections.remove(LOCAL_CONNECTION_ID);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
int idx = connection.getId().indexOf(RESERVED_ID_CHAR);
|
||||||
|
if (idx == -1)
|
||||||
|
{
|
||||||
|
sharedConnections.remove(connection.getId());
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
userConnections.remove(connection.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally
|
||||||
|
{
|
||||||
|
lock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<CMISServer> getServerDefinitions()
|
||||||
|
{
|
||||||
|
return servers == null ? null : servers.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CMISServer getServerDefinition(String serverName)
|
||||||
|
{
|
||||||
|
return servers == null ? null : servers.get(serverName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CMISServer createServerDefinition(String serverName, Map<String, String> parameters)
|
||||||
|
{
|
||||||
|
return new CMISServerImpl(serverName, null, parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CMISServer createServerDefinition(CMISServer server, String username, String password)
|
||||||
|
{
|
||||||
|
if (server == null)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Server must be set!");
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, String> parameters = new HashMap<String, String>(server.getParameters());
|
||||||
|
parameters.put(SessionParameter.USER, username);
|
||||||
|
parameters.put(SessionParameter.PASSWORD, password);
|
||||||
|
|
||||||
|
return new CMISServerImpl(server.getName(), server.getDescription(), parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CMISServer createServerDefinition(CMISServer server, String username, String password, String repositoryId)
|
||||||
|
{
|
||||||
|
if (server == null)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Server must be set!");
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, String> parameters = new HashMap<String, String>(server.getParameters());
|
||||||
|
parameters.put(SessionParameter.USER, username);
|
||||||
|
parameters.put(SessionParameter.PASSWORD, password);
|
||||||
|
parameters.put(SessionParameter.REPOSITORY_ID, repositoryId);
|
||||||
|
|
||||||
|
return new CMISServerImpl(server.getName(), server.getDescription(), parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Repository> getRepositories(CMISServer server)
|
||||||
|
{
|
||||||
|
if (server == null)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Server must be set!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return sessionFactory.getRepositories(server.getParameters());
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2011 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.cmis.client;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.alfresco.opencmis.AlfrescoLocalCmisServiceFactory;
|
||||||
|
import org.alfresco.opencmis.CMISConnector;
|
||||||
|
import org.apache.chemistry.opencmis.client.api.Session;
|
||||||
|
import org.apache.chemistry.opencmis.commons.SessionParameter;
|
||||||
|
import org.apache.chemistry.opencmis.commons.enums.BindingType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CMIS Connection manager with a local default connection.
|
||||||
|
*/
|
||||||
|
public class CMISLocalConnectionManagerImpl extends AbstractCMISConnectionManagerImpl implements CMISConnectionManager
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Sets the CMIS connector.
|
||||||
|
*/
|
||||||
|
public void setCmisConnector(CMISConnector connector)
|
||||||
|
{
|
||||||
|
AlfrescoLocalCmisServiceFactory.setCmisConnector(connector);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a local connection.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public CMISConnection getConnection()
|
||||||
|
{
|
||||||
|
lock.writeLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
CMISConnection connection = getUserConnections(LOCAL_CONNECTION_ID);
|
||||||
|
if (connection != null)
|
||||||
|
{
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
String currentUser = authenticationService.getCurrentUserName();
|
||||||
|
|
||||||
|
Map<String, String> parameters = new HashMap<String, String>();
|
||||||
|
parameters.put(SessionParameter.BINDING_TYPE, BindingType.LOCAL.value());
|
||||||
|
parameters.put(SessionParameter.LOCAL_FACTORY, AlfrescoLocalCmisServiceFactory.class.getName());
|
||||||
|
parameters.put(SessionParameter.USER, currentUser);
|
||||||
|
|
||||||
|
CMISServer server = createServerDefinition("local", parameters);
|
||||||
|
Session session = createSession(server.getParameters());
|
||||||
|
connection = new CMISConnectionImpl(this, LOCAL_CONNECTION_ID, session, server, currentUser, true);
|
||||||
|
|
||||||
|
String userConnectionId = createUserConnectionId(currentUser, LOCAL_CONNECTION_ID);
|
||||||
|
|
||||||
|
userConnections.put(userConnectionId, connection);
|
||||||
|
|
||||||
|
return connection;
|
||||||
|
} finally
|
||||||
|
{
|
||||||
|
lock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2011 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.cmis.client;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CMIS Connection manager with a remote default connection.
|
||||||
|
*/
|
||||||
|
public class CMISRemoteConnectionManagerImpl extends AbstractCMISConnectionManagerImpl implements CMISConnectionManager
|
||||||
|
{
|
||||||
|
private CMISServer defaultServer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the remote server details.
|
||||||
|
*/
|
||||||
|
public void setDefaultServer(Map<String, String> defaultServerProperties)
|
||||||
|
{
|
||||||
|
defaultServer = createServerDefinition(defaultServerProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a remote connection.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public CMISConnection getConnection()
|
||||||
|
{
|
||||||
|
lock.writeLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
CMISConnection connection = getUserConnections(LOCAL_CONNECTION_ID);
|
||||||
|
if (connection != null)
|
||||||
|
{
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
String currentUser = authenticationService.getCurrentUserName();
|
||||||
|
|
||||||
|
if (defaultServer == null)
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("No default server defined!");
|
||||||
|
}
|
||||||
|
|
||||||
|
CMISServer server = createServerDefinition(defaultServer, currentUser, null);
|
||||||
|
|
||||||
|
return createUserConnection(server, LOCAL_CONNECTION_ID);
|
||||||
|
} finally
|
||||||
|
{
|
||||||
|
lock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
48
source/java/org/alfresco/repo/cmis/client/CMISServer.java
Normal file
48
source/java/org/alfresco/repo/cmis/client/CMISServer.java
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2011 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.cmis.client;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CMIS server definition.
|
||||||
|
*/
|
||||||
|
public interface CMISServer
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Gets CMIS Server Name
|
||||||
|
*
|
||||||
|
* @return server name
|
||||||
|
*/
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets CMIS Server Description
|
||||||
|
*
|
||||||
|
* @return server description
|
||||||
|
*/
|
||||||
|
String getDescription();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets CMIS Server Parameters
|
||||||
|
*
|
||||||
|
* @return server parameters
|
||||||
|
*/
|
||||||
|
Map<String, String> getParameters();
|
||||||
|
}
|
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2011 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.cmis.client;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class CMISServerImpl implements CMISServer
|
||||||
|
{
|
||||||
|
private String name;
|
||||||
|
private String description;
|
||||||
|
private Map<String, String> parameters;
|
||||||
|
|
||||||
|
public CMISServerImpl(String name, String description, Map<String, String> parameters)
|
||||||
|
{
|
||||||
|
if (name == null)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Name must be set!");
|
||||||
|
}
|
||||||
|
if (parameters == null)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Parameters must be set!");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.name = name;
|
||||||
|
this.description = description;
|
||||||
|
this.parameters = new HashMap<String, String>(parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription()
|
||||||
|
{
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> getParameters()
|
||||||
|
{
|
||||||
|
return Collections.unmodifiableMap(parameters);
|
||||||
|
}
|
||||||
|
}
|
@@ -20,8 +20,8 @@ package org.alfresco.repo.cmis.ws;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.alfresco.repo.security.authentication.Authorization;
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||||
import org.alfresco.repo.web.util.auth.Authorization;
|
|
||||||
import org.alfresco.service.cmr.security.AuthenticationService;
|
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||||
import org.alfresco.service.transaction.TransactionService;
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
import org.apache.cxf.binding.soap.SoapMessage;
|
import org.apache.cxf.binding.soap.SoapMessage;
|
||||||
|
@@ -22,14 +22,14 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationException;
|
import org.alfresco.repo.security.authentication.AuthenticationException;
|
||||||
import org.alfresco.repo.web.util.auth.Authorization;
|
import org.alfresco.repo.security.authentication.Authorization;
|
||||||
import org.alfresco.service.cmr.security.AuthenticationService;
|
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.springframework.extensions.surf.util.Base64;
|
import org.springframework.extensions.surf.util.Base64;
|
||||||
import org.springframework.extensions.webscripts.Authenticator;
|
import org.springframework.extensions.webscripts.Authenticator;
|
||||||
import org.springframework.extensions.webscripts.WebScriptException;
|
|
||||||
import org.springframework.extensions.webscripts.Description.RequiredAuthentication;
|
import org.springframework.extensions.webscripts.Description.RequiredAuthentication;
|
||||||
|
import org.springframework.extensions.webscripts.WebScriptException;
|
||||||
import org.springframework.extensions.webscripts.servlet.ServletAuthenticatorFactory;
|
import org.springframework.extensions.webscripts.servlet.ServletAuthenticatorFactory;
|
||||||
import org.springframework.extensions.webscripts.servlet.WebScriptServletRequest;
|
import org.springframework.extensions.webscripts.servlet.WebScriptServletRequest;
|
||||||
import org.springframework.extensions.webscripts.servlet.WebScriptServletResponse;
|
import org.springframework.extensions.webscripts.servlet.WebScriptServletResponse;
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
package org.alfresco.repo.web.scripts.solr;
|
package org.alfresco.repo.web.scripts.solr;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@@ -14,6 +15,10 @@ import org.alfresco.repo.domain.solr.SOLRDAO.NodeQueryCallback;
|
|||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.springframework.extensions.surf.util.Content;
|
||||||
import org.springframework.extensions.webscripts.DeclarativeWebScript;
|
import org.springframework.extensions.webscripts.DeclarativeWebScript;
|
||||||
import org.springframework.extensions.webscripts.Status;
|
import org.springframework.extensions.webscripts.Status;
|
||||||
import org.springframework.extensions.webscripts.WebScriptException;
|
import org.springframework.extensions.webscripts.WebScriptException;
|
||||||
@@ -49,73 +54,77 @@ public class GetNodes extends DeclarativeWebScript
|
|||||||
@Override
|
@Override
|
||||||
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status)
|
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status)
|
||||||
{
|
{
|
||||||
String txnIdsString = req.getParameter("txnIds");
|
try
|
||||||
if(txnIdsString == null)
|
|
||||||
{
|
{
|
||||||
throw new WebScriptException("txnIds parameter is required for GetNodes");
|
Content content = req.getContent();
|
||||||
|
if(content == null)
|
||||||
|
{
|
||||||
|
throw new WebScriptException("Failed to convert request to String");
|
||||||
}
|
}
|
||||||
|
JSONObject o = new JSONObject(content.getContent());
|
||||||
|
|
||||||
String param = req.getParameter("fromNodeId");
|
JSONArray aTxnIds = o.has("txnIds") ? o.getJSONArray("txnIds") : null;
|
||||||
Long fromNodeId = (param == null ? null : Long.valueOf(param));
|
Long fromTxnId = o.has("fromTxnId") ? o.getLong("fromTxnId") : null;
|
||||||
|
Long toTxnId = o.has("toTxnId") ? o.getLong("toTxnId") : null;
|
||||||
|
|
||||||
param = req.getParameter("toNodeId");
|
Long fromNodeId = o.has("fromNodeId") ? o.getLong("fromNodeId") : null;
|
||||||
Long toNodeId = (param == null ? null : Long.valueOf(param));
|
Long toNodeId = o.has("toNodeId") ? o.getLong("toNodeId") : null;
|
||||||
|
|
||||||
param = req.getParameter("excludeAspects");
|
|
||||||
Set<QName> excludeAspects = null;
|
Set<QName> excludeAspects = null;
|
||||||
if(param != null)
|
if(o.has("excludeAspects"))
|
||||||
{
|
{
|
||||||
String[] excludeAspectsStrings = param.split(",");
|
JSONArray aExcludeAspects = o.getJSONArray("excludeAspects");
|
||||||
excludeAspects = new HashSet<QName>(excludeAspectsStrings.length);
|
excludeAspects = new HashSet<QName>(aExcludeAspects.length());
|
||||||
for(String excludeAspect : excludeAspectsStrings)
|
for(int i = 0; i < aExcludeAspects.length(); i++)
|
||||||
{
|
{
|
||||||
excludeAspects.add(QName.createQName(excludeAspect.trim()));
|
excludeAspects.add(QName.createQName(aExcludeAspects.getString(i).trim()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
param = req.getParameter("includeAspects");
|
|
||||||
Set<QName> includeAspects = null;
|
Set<QName> includeAspects = null;
|
||||||
if(param != null)
|
if(o.has("includeAspects"))
|
||||||
{
|
{
|
||||||
String[] includeAspectsStrings = param.split(",");
|
JSONArray aIncludeAspects = o.getJSONArray("includeAspects");
|
||||||
includeAspects = new HashSet<QName>(includeAspectsStrings.length);
|
includeAspects = new HashSet<QName>(aIncludeAspects.length());
|
||||||
for(String includeAspect : includeAspectsStrings)
|
for(int i = 0; i < aIncludeAspects.length(); i++)
|
||||||
{
|
{
|
||||||
includeAspects.add(QName.createQName(includeAspect.trim()));
|
includeAspects.add(QName.createQName(aIncludeAspects.getString(i).trim()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
param = req.getParameter("maxResults");
|
// 0 or Integer.MAX_VALUE => ignore
|
||||||
int maxResults = (param == null ? 0 : Integer.valueOf(param));
|
int maxResults = o.has("maxResults") ? o.getInt("maxResults") : 0;
|
||||||
|
|
||||||
param = req.getParameter("storeProtocol");
|
String storeProtocol = o.has("storeProtocol") ? o.getString("storeProtocol") : null;
|
||||||
String storeProtocol = param;
|
String storeIdentifier = o.has("storeIdentifier") ? o.getString("storeIdentifier") : null;
|
||||||
|
|
||||||
param = req.getParameter("storeIdentifier");
|
List<Long> txnIds = null;
|
||||||
String storeIdentifier = param;
|
if(aTxnIds != null)
|
||||||
|
|
||||||
String[] txnIdStrings = txnIdsString.split(",");
|
|
||||||
List<Long> txnIds = new ArrayList<Long>(txnIdStrings.length);
|
|
||||||
for(String txnIdString : txnIdStrings)
|
|
||||||
{
|
{
|
||||||
txnIds.add(Long.valueOf(txnIdString.trim()));
|
txnIds = new ArrayList<Long>(aTxnIds.length());
|
||||||
|
for(int i = 0; i < aTxnIds.length(); i++)
|
||||||
|
{
|
||||||
|
txnIds.add(aTxnIds.getLong(i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WebNodeQueryCallback nodeQueryCallback = new WebNodeQueryCallback(maxResults);
|
WebNodeQueryCallback nodeQueryCallback = new WebNodeQueryCallback(maxResults);
|
||||||
NodeParameters nodeParameters = new NodeParameters();
|
NodeParameters nodeParameters = new NodeParameters();
|
||||||
nodeParameters.setTransactionIds(txnIds);
|
nodeParameters.setTransactionIds(txnIds);
|
||||||
|
nodeParameters.setFromTxnId(fromTxnId);
|
||||||
|
nodeParameters.setToTxnId(toTxnId);
|
||||||
nodeParameters.setFromNodeId(fromNodeId);
|
nodeParameters.setFromNodeId(fromNodeId);
|
||||||
nodeParameters.setToNodeId(toNodeId);
|
nodeParameters.setToNodeId(toNodeId);
|
||||||
nodeParameters.setExcludeAspects(excludeAspects);
|
nodeParameters.setExcludeAspects(excludeAspects);
|
||||||
nodeParameters.setIncludeAspects(includeAspects);
|
nodeParameters.setIncludeAspects(includeAspects);
|
||||||
nodeParameters.setStoreProtocol(storeProtocol);
|
nodeParameters.setStoreProtocol(storeProtocol);
|
||||||
nodeParameters.setStoreIdentifier(storeIdentifier);
|
nodeParameters.setStoreIdentifier(storeIdentifier);
|
||||||
solrDAO.getNodes(nodeParameters, maxResults, nodeQueryCallback);
|
nodeParameters.setMaxResults(maxResults);
|
||||||
|
solrDAO.getNodes(nodeParameters, nodeQueryCallback);
|
||||||
|
|
||||||
Map<String, Object> model = new HashMap<String, Object>(2, 1.0f);
|
Map<String, Object> model = new HashMap<String, Object>(1, 1.0f);
|
||||||
List<Node> nodes = nodeQueryCallback.getNodes();
|
List<Node> nodes = nodeQueryCallback.getNodes();
|
||||||
model.put("nodes", nodes);
|
model.put("nodes", nodes);
|
||||||
model.put("count", nodes.size());
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
@@ -124,9 +133,18 @@ public class GetNodes extends DeclarativeWebScript
|
|||||||
|
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
catch(IOException e)
|
||||||
|
{
|
||||||
|
throw new WebScriptException("IO exception parsing request", e);
|
||||||
|
}
|
||||||
|
catch(JSONException e)
|
||||||
|
{
|
||||||
|
throw new WebScriptException("Invalid JSON", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Callback for DAO get nodes query
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private static class WebNodeQueryCallback implements NodeQueryCallback
|
private static class WebNodeQueryCallback implements NodeQueryCallback
|
||||||
|
@@ -0,0 +1,308 @@
|
|||||||
|
package org.alfresco.repo.web.scripts.solr;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.alfresco.repo.domain.node.ContentDataWithId;
|
||||||
|
import org.alfresco.repo.domain.solr.MetaDataResultsFilter;
|
||||||
|
import org.alfresco.repo.domain.solr.NodeMetaData;
|
||||||
|
import org.alfresco.repo.domain.solr.NodeMetaDataParameters;
|
||||||
|
import org.alfresco.repo.domain.solr.SOLRDAO;
|
||||||
|
import org.alfresco.repo.domain.solr.SOLRDAO.NodeMetaDataQueryCallback;
|
||||||
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.Path;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.alfresco.util.SOLRSerializer;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.springframework.extensions.surf.util.Content;
|
||||||
|
import org.springframework.extensions.webscripts.DeclarativeWebScript;
|
||||||
|
import org.springframework.extensions.webscripts.Status;
|
||||||
|
import org.springframework.extensions.webscripts.WebScriptException;
|
||||||
|
import org.springframework.extensions.webscripts.WebScriptRequest;
|
||||||
|
|
||||||
|
// TODO how to hook into bulk loading of nodes + properties + aspects?
|
||||||
|
// todo url parameter to remove whitespace in results - make it the default?
|
||||||
|
public class GetNodesMetaData extends DeclarativeWebScript
|
||||||
|
{
|
||||||
|
protected static final Log logger = LogFactory.getLog(GetNodesMetaData.class);
|
||||||
|
private static final int INITIAL_DEFAULT_SIZE = 100;
|
||||||
|
private static final int BATCH_SIZE = 50;
|
||||||
|
|
||||||
|
private SOLRDAO solrDAO;
|
||||||
|
private SOLRSerializer solrSerializer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param solrDAO the solrDAO to set
|
||||||
|
*/
|
||||||
|
public void setSolrDAO(SOLRDAO solrDAO)
|
||||||
|
{
|
||||||
|
this.solrDAO = solrDAO;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSolrSerializer(SOLRSerializer solrSerializer)
|
||||||
|
{
|
||||||
|
this.solrSerializer = solrSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.Status)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected Map<String, Object> executeImpl(WebScriptRequest req, Status status)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Content content = req.getContent();
|
||||||
|
if(content == null)
|
||||||
|
{
|
||||||
|
throw new WebScriptException("Failed to convert request to String");
|
||||||
|
}
|
||||||
|
JSONObject o = new JSONObject(content.getContent());
|
||||||
|
|
||||||
|
List<Long> nodeIds = null;
|
||||||
|
if(o.has("nodeIds"))
|
||||||
|
{
|
||||||
|
JSONArray jsonNodeIds = o.getJSONArray("nodeIds");
|
||||||
|
nodeIds = new ArrayList<Long>(jsonNodeIds.length());
|
||||||
|
for(int i = 0; i < jsonNodeIds.length(); i++)
|
||||||
|
{
|
||||||
|
Long nodeId = jsonNodeIds.getLong(i);
|
||||||
|
nodeIds.add(nodeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Long fromNodeId = o.has("fromNodeId") ? o.getLong("fromNodeId") : null;
|
||||||
|
Long toNodeId = o.has("toNodeId") ? o.getLong("toNodeId") : null;
|
||||||
|
|
||||||
|
// 0 or Integer.MAX_VALUE => ignore
|
||||||
|
int maxResults = o.has("maxResults") ? o.getInt("maxResults") : 0;
|
||||||
|
|
||||||
|
int size = 0;
|
||||||
|
if(maxResults != 0 && maxResults != Integer.MAX_VALUE)
|
||||||
|
{
|
||||||
|
size = maxResults;
|
||||||
|
}
|
||||||
|
else if(nodeIds != null)
|
||||||
|
{
|
||||||
|
size = nodeIds.size();
|
||||||
|
}
|
||||||
|
else if(fromNodeId != null && toNodeId != null)
|
||||||
|
{
|
||||||
|
if((toNodeId.longValue() - fromNodeId.longValue()) > Integer.MAX_VALUE)
|
||||||
|
{
|
||||||
|
throw new WebScriptException("Too many nodes expected, try changing the criteria");
|
||||||
|
}
|
||||||
|
size = (int)(toNodeId - fromNodeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean noSizeCalculated = (size == 0);
|
||||||
|
|
||||||
|
// filters, defaults are 'true'
|
||||||
|
MetaDataResultsFilter filter = new MetaDataResultsFilter();
|
||||||
|
if(o.has("includeAclId"))
|
||||||
|
{
|
||||||
|
filter.setIncludeAclId(o.getBoolean("includeAclId"));
|
||||||
|
}
|
||||||
|
if(o.has("includeAspects"))
|
||||||
|
{
|
||||||
|
filter.setIncludeAspects(o.getBoolean("includeAspects"));
|
||||||
|
}
|
||||||
|
if(o.has("includeNodeRef"))
|
||||||
|
{
|
||||||
|
filter.setIncludeNodeRef(o.getBoolean("includeNodeRef"));
|
||||||
|
}
|
||||||
|
if(o.has("includeOwner"))
|
||||||
|
{
|
||||||
|
filter.setIncludeOwner(o.getBoolean("includeOwner"));
|
||||||
|
}
|
||||||
|
if(o.has("includeProperties"))
|
||||||
|
{
|
||||||
|
filter.setIncludeProperties(o.getBoolean("includeProperties"));
|
||||||
|
}
|
||||||
|
if(o.has("includePaths"))
|
||||||
|
{
|
||||||
|
filter.setIncludePaths(o.getBoolean("includePaths"));
|
||||||
|
}
|
||||||
|
if(o.has("includeType"))
|
||||||
|
{
|
||||||
|
filter.setIncludeType(o.getBoolean("includeType"));
|
||||||
|
}
|
||||||
|
if(o.has("includeAssociations"))
|
||||||
|
{
|
||||||
|
filter.setIncludeAssociations(o.getBoolean("includeAssociations"));
|
||||||
|
}
|
||||||
|
|
||||||
|
final ArrayList<FreemarkerNodeMetaData> nodesMetaData =
|
||||||
|
new ArrayList<FreemarkerNodeMetaData>(size > 0 ? size : INITIAL_DEFAULT_SIZE);
|
||||||
|
NodeMetaDataParameters params = new NodeMetaDataParameters();
|
||||||
|
params.setNodeIds(nodeIds);
|
||||||
|
params.setFromNodeId(fromNodeId);
|
||||||
|
params.setToNodeId(toNodeId);
|
||||||
|
params.setMaxResults(maxResults);
|
||||||
|
|
||||||
|
solrDAO.getNodesMetadata(params, filter, new NodeMetaDataQueryCallback()
|
||||||
|
{
|
||||||
|
private int counter = BATCH_SIZE;
|
||||||
|
private int numBatches = 0;
|
||||||
|
|
||||||
|
public boolean handleNodeMetaData(NodeMetaData nodeMetaData)
|
||||||
|
{
|
||||||
|
// need to perform data structure conversions that are compatible with Freemarker
|
||||||
|
// e.g. Serializable -> String, QName -> String (because map keys must be string, number)
|
||||||
|
FreemarkerNodeMetaData fNodeMetaData = new FreemarkerNodeMetaData(solrSerializer, nodeMetaData);
|
||||||
|
nodesMetaData.add(fNodeMetaData);
|
||||||
|
|
||||||
|
if(noSizeCalculated && --counter == 0)
|
||||||
|
{
|
||||||
|
counter = BATCH_SIZE;
|
||||||
|
nodesMetaData.ensureCapacity(++numBatches*BATCH_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Map<String, Object> model = new HashMap<String, Object>(1, 1.0f);
|
||||||
|
model.put("nodes", nodesMetaData);
|
||||||
|
model.put("filter", filter);
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
|
||||||
|
}
|
||||||
|
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
catch(IOException e)
|
||||||
|
{
|
||||||
|
throw new WebScriptException("IO exception parsing request", e);
|
||||||
|
}
|
||||||
|
catch(JSONException e)
|
||||||
|
{
|
||||||
|
throw new WebScriptException("Invalid JSON", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class FreemarkerNodeMetaData
|
||||||
|
{
|
||||||
|
private Long nodeId;
|
||||||
|
private NodeRef nodeRef;
|
||||||
|
private QName nodeType;
|
||||||
|
private Long aclId;
|
||||||
|
private Map<String, Object> properties;
|
||||||
|
private Set<QName> aspects;
|
||||||
|
private List<Path> paths;
|
||||||
|
private List<ChildAssociationRef> childAssocs;
|
||||||
|
|
||||||
|
public FreemarkerNodeMetaData(SOLRSerializer solrSerializer, NodeMetaData nodeMetaData)
|
||||||
|
{
|
||||||
|
setNodeId(nodeMetaData.getNodeId());
|
||||||
|
setAclId(nodeMetaData.getAclId());
|
||||||
|
setNodeRef(nodeMetaData.getNodeRef());
|
||||||
|
setNodeType(nodeMetaData.getNodeType());
|
||||||
|
|
||||||
|
// TODO need to use SOLRTypeConverter to serialize Path
|
||||||
|
for(Path path : nodeMetaData.getPaths())
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
setPaths(nodeMetaData.getPaths());
|
||||||
|
setChildAssocs(nodeMetaData.getChildAssocs());
|
||||||
|
setAspects(nodeMetaData.getAspects());
|
||||||
|
Map<QName, Serializable> props = nodeMetaData.getProperties();
|
||||||
|
Map<String, Object> properties = (props != null ? new HashMap<String, Object>(props.size()) : null);
|
||||||
|
for(QName propName : props.keySet())
|
||||||
|
{
|
||||||
|
Serializable value = props.get(propName);
|
||||||
|
|
||||||
|
if(value instanceof ContentDataWithId)
|
||||||
|
{
|
||||||
|
// special case - ContentDataWithId
|
||||||
|
properties.put(propName.toString(), ((ContentDataWithId)value).getId());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
properties.put(propName.toString(), solrSerializer.serialize(propName, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setProperties(properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NodeRef getNodeRef()
|
||||||
|
{
|
||||||
|
return nodeRef;
|
||||||
|
}
|
||||||
|
public void setNodeRef(NodeRef nodeRef)
|
||||||
|
{
|
||||||
|
this.nodeRef = nodeRef;
|
||||||
|
}
|
||||||
|
public List<Path> getPaths()
|
||||||
|
{
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
public void setPaths(List<Path> paths)
|
||||||
|
{
|
||||||
|
this.paths = paths;
|
||||||
|
}
|
||||||
|
public QName getNodeType()
|
||||||
|
{
|
||||||
|
return nodeType;
|
||||||
|
}
|
||||||
|
public void setNodeType(QName nodeType)
|
||||||
|
{
|
||||||
|
this.nodeType = nodeType;
|
||||||
|
}
|
||||||
|
public Long getNodeId()
|
||||||
|
{
|
||||||
|
return nodeId;
|
||||||
|
}
|
||||||
|
public void setNodeId(Long nodeId)
|
||||||
|
{
|
||||||
|
this.nodeId = nodeId;
|
||||||
|
}
|
||||||
|
public Long getAclId()
|
||||||
|
{
|
||||||
|
return aclId;
|
||||||
|
}
|
||||||
|
public void setAclId(Long aclId)
|
||||||
|
{
|
||||||
|
this.aclId = aclId;
|
||||||
|
}
|
||||||
|
public Map<String, Object> getProperties()
|
||||||
|
{
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
public void setProperties(Map<String, Object> properties)
|
||||||
|
{
|
||||||
|
this.properties = properties;
|
||||||
|
}
|
||||||
|
public Set<QName> getAspects()
|
||||||
|
{
|
||||||
|
return aspects;
|
||||||
|
}
|
||||||
|
public void setAspects(Set<QName> aspects)
|
||||||
|
{
|
||||||
|
this.aspects = aspects;
|
||||||
|
}
|
||||||
|
public List<ChildAssociationRef> getChildAssocs()
|
||||||
|
{
|
||||||
|
return childAssocs;
|
||||||
|
}
|
||||||
|
public void setChildAssocs(List<ChildAssociationRef> childAssocs)
|
||||||
|
{
|
||||||
|
this.childAssocs = childAssocs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,118 @@
|
|||||||
|
package org.alfresco.repo.web.scripts.solr;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
|
public class GetNodesParameters
|
||||||
|
{
|
||||||
|
private List<Long> transactionIds;
|
||||||
|
private Long fromNodeId;
|
||||||
|
private Long toNodeId;
|
||||||
|
|
||||||
|
private String storeProtocol;
|
||||||
|
private String storeIdentifier;
|
||||||
|
|
||||||
|
private Set<QName> includeNodeTypes;
|
||||||
|
private Set<QName> excludeNodeTypes;
|
||||||
|
|
||||||
|
private Set<QName> includeAspects;
|
||||||
|
private Set<QName> excludeAspects;
|
||||||
|
|
||||||
|
public boolean getStoreFilter()
|
||||||
|
{
|
||||||
|
return (storeProtocol != null || storeIdentifier != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStoreProtocol(String storeProtocol)
|
||||||
|
{
|
||||||
|
this.storeProtocol = storeProtocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStoreProtocol()
|
||||||
|
{
|
||||||
|
return storeProtocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStoreIdentifier(String storeIdentifier)
|
||||||
|
{
|
||||||
|
this.storeIdentifier = storeIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStoreIdentifier()
|
||||||
|
{
|
||||||
|
return storeIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransactionIds(List<Long> txnIds)
|
||||||
|
{
|
||||||
|
this.transactionIds = txnIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Long> getTransactionIds()
|
||||||
|
{
|
||||||
|
return transactionIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getFromNodeId()
|
||||||
|
{
|
||||||
|
return fromNodeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFromNodeId(Long fromNodeId)
|
||||||
|
{
|
||||||
|
this.fromNodeId = fromNodeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getToNodeId()
|
||||||
|
{
|
||||||
|
return toNodeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToNodeId(Long toNodeId)
|
||||||
|
{
|
||||||
|
this.toNodeId = toNodeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<QName> getIncludeNodeTypes()
|
||||||
|
{
|
||||||
|
return includeNodeTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<QName> getExcludeNodeTypes()
|
||||||
|
{
|
||||||
|
return excludeNodeTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<QName> getIncludeAspects()
|
||||||
|
{
|
||||||
|
return includeAspects;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<QName> getExcludeAspects()
|
||||||
|
{
|
||||||
|
return excludeAspects;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIncludeNodeTypes(Set<QName> includeNodeTypes)
|
||||||
|
{
|
||||||
|
this.includeNodeTypes = includeNodeTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExcludeNodeTypes(Set<QName> excludeNodeTypes)
|
||||||
|
{
|
||||||
|
this.excludeNodeTypes = excludeNodeTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIncludeAspects(Set<QName> includeAspects)
|
||||||
|
{
|
||||||
|
this.includeAspects = includeAspects;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExcludeAspects(Set<QName> excludeAspects)
|
||||||
|
{
|
||||||
|
this.excludeAspects = excludeAspects;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -10,7 +10,6 @@ import org.apache.commons.logging.Log;
|
|||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.springframework.extensions.webscripts.DeclarativeWebScript;
|
import org.springframework.extensions.webscripts.DeclarativeWebScript;
|
||||||
import org.springframework.extensions.webscripts.Status;
|
import org.springframework.extensions.webscripts.Status;
|
||||||
import org.springframework.extensions.webscripts.WebScriptException;
|
|
||||||
import org.springframework.extensions.webscripts.WebScriptRequest;
|
import org.springframework.extensions.webscripts.WebScriptRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -18,6 +17,8 @@ import org.springframework.extensions.webscripts.WebScriptRequest;
|
|||||||
*
|
*
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
|
// TODO check that this does not return incomplete transactions i.e. commitTimeMs is set - does
|
||||||
|
// the sql account for this?
|
||||||
public class GetTransactions extends DeclarativeWebScript
|
public class GetTransactions extends DeclarativeWebScript
|
||||||
{
|
{
|
||||||
protected static final Log logger = LogFactory.getLog(GetTransactions.class);
|
protected static final Log logger = LogFactory.getLog(GetTransactions.class);
|
||||||
|
399
source/java/org/alfresco/repo/web/scripts/solr/JSONWriter.java
Normal file
399
source/java/org/alfresco/repo/web/scripts/solr/JSONWriter.java
Normal file
@@ -0,0 +1,399 @@
|
|||||||
|
package org.alfresco.repo.web.scripts.solr;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.util.Stack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fast and simple JSON stream writer. Wraps a Writer to output a JSON object stream.
|
||||||
|
* No intermediate objects are created - writes are immediate to the underlying stream.
|
||||||
|
* Quoted and correct JSON encoding is performed on string values, - encoding is
|
||||||
|
* not performed on key names - it is assumed they are simple strings. The developer must
|
||||||
|
* call JSONWriter.encodeJSONString() on the key name if required.
|
||||||
|
*
|
||||||
|
* @author Kevin Roast
|
||||||
|
* @author Steve Glover
|
||||||
|
*
|
||||||
|
* Adapted from org.springframework.extensions.webscripts.json.
|
||||||
|
* - added writeValue methods for class versions of primitives
|
||||||
|
*/
|
||||||
|
public final class JSONWriter
|
||||||
|
{
|
||||||
|
private Writer out;
|
||||||
|
private Stack<Boolean> stack = new Stack<Boolean>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param out The Writer to immediately append values to (no internal buffering)
|
||||||
|
*/
|
||||||
|
public JSONWriter(Writer out)
|
||||||
|
{
|
||||||
|
this.out = out;
|
||||||
|
stack.push(Boolean.FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start an array structure, the endArray() method must be called later.
|
||||||
|
* NOTE: Within the array, either output objects or use the single arg writeValue() method.
|
||||||
|
*/
|
||||||
|
public void startArray() throws IOException
|
||||||
|
{
|
||||||
|
if (stack.peek() == true) out.write(", ");
|
||||||
|
out.write("[");
|
||||||
|
stack.pop();
|
||||||
|
stack.push(Boolean.TRUE);
|
||||||
|
stack.push(Boolean.FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End an array structure.
|
||||||
|
*/
|
||||||
|
public void endArray() throws IOException
|
||||||
|
{
|
||||||
|
out.write("]");
|
||||||
|
stack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start an object structure, the endObject() method must be called later.
|
||||||
|
*/
|
||||||
|
public void startObject() throws IOException
|
||||||
|
{
|
||||||
|
if (stack.peek() == true) out.write(", ");
|
||||||
|
out.write("{");
|
||||||
|
stack.pop();
|
||||||
|
stack.push(Boolean.TRUE);
|
||||||
|
stack.push(Boolean.FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End an object structure.
|
||||||
|
*/
|
||||||
|
public void endObject() throws IOException
|
||||||
|
{
|
||||||
|
out.write("}");
|
||||||
|
stack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start a value (outputs just a name key), the endValue() method must be called later.
|
||||||
|
* NOTE: follow with an array or object only.
|
||||||
|
*/
|
||||||
|
public void startValue(String name) throws IOException
|
||||||
|
{
|
||||||
|
if (stack.peek() == true) out.write(", ");
|
||||||
|
out.write('"');
|
||||||
|
out.write(name);
|
||||||
|
out.write("\": ");
|
||||||
|
stack.pop();
|
||||||
|
stack.push(Boolean.TRUE);
|
||||||
|
stack.push(Boolean.FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End a value that was started with startValue()
|
||||||
|
*/
|
||||||
|
public void endValue()
|
||||||
|
{
|
||||||
|
stack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output a JSON string name and value pair.
|
||||||
|
*/
|
||||||
|
public void writeValue(String name, String value) throws IOException
|
||||||
|
{
|
||||||
|
if (stack.peek() == true) out.write(", ");
|
||||||
|
out.write('"');
|
||||||
|
out.write(name);
|
||||||
|
out.write("\": \"");
|
||||||
|
out.write(encodeJSONString(value));
|
||||||
|
out.write('"');
|
||||||
|
stack.pop();
|
||||||
|
stack.push(Boolean.TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output a JSON number name and value pair.
|
||||||
|
*/
|
||||||
|
public void writeValue(String name, int value) throws IOException
|
||||||
|
{
|
||||||
|
if (stack.peek() == true) out.write(", ");
|
||||||
|
out.write('"');
|
||||||
|
out.write(name);
|
||||||
|
out.write("\": ");
|
||||||
|
out.write(Integer.toString(value));
|
||||||
|
stack.pop();
|
||||||
|
stack.push(Boolean.TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeValue(String name, Integer value) throws IOException
|
||||||
|
{
|
||||||
|
if (stack.peek() == true) out.write(", ");
|
||||||
|
out.write('"');
|
||||||
|
out.write(name);
|
||||||
|
out.write("\": ");
|
||||||
|
out.write(value.toString());
|
||||||
|
stack.pop();
|
||||||
|
stack.push(Boolean.TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output a JSON number name and value pair.
|
||||||
|
*/
|
||||||
|
public void writeValue(String name, float value) throws IOException
|
||||||
|
{
|
||||||
|
if (stack.peek() == true) out.write(", ");
|
||||||
|
out.write('"');
|
||||||
|
out.write(name);
|
||||||
|
out.write("\": ");
|
||||||
|
out.write(Float.toString(value));
|
||||||
|
stack.pop();
|
||||||
|
stack.push(Boolean.TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeValue(String name, Float value) throws IOException
|
||||||
|
{
|
||||||
|
if (stack.peek() == true) out.write(", ");
|
||||||
|
out.write('"');
|
||||||
|
out.write(name);
|
||||||
|
out.write("\": ");
|
||||||
|
out.write(value.toString());
|
||||||
|
stack.pop();
|
||||||
|
stack.push(Boolean.TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output a JSON boolean name and value pair.
|
||||||
|
*/
|
||||||
|
public void writeValue(String name, boolean value) throws IOException
|
||||||
|
{
|
||||||
|
if (stack.peek() == true) out.write(", ");
|
||||||
|
out.write('"');
|
||||||
|
out.write(name);
|
||||||
|
out.write("\": ");
|
||||||
|
out.write(Boolean.toString(value));
|
||||||
|
stack.pop();
|
||||||
|
stack.push(Boolean.TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeValue(String name, Boolean value) throws IOException
|
||||||
|
{
|
||||||
|
if (stack.peek() == true) out.write(", ");
|
||||||
|
out.write('"');
|
||||||
|
out.write(name);
|
||||||
|
out.write("\": ");
|
||||||
|
out.write(value.toString());
|
||||||
|
stack.pop();
|
||||||
|
stack.push(Boolean.TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output a JSON string value.
|
||||||
|
* NOTE: no name is written - call from within an array structure.
|
||||||
|
*/
|
||||||
|
public void writeValue(String value) throws IOException
|
||||||
|
{
|
||||||
|
if (stack.peek() == true) out.write(",");
|
||||||
|
out.write('"');
|
||||||
|
out.write(encodeJSONString(value));
|
||||||
|
out.write('"');
|
||||||
|
stack.pop();
|
||||||
|
stack.push(Boolean.TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output a JSON number value.
|
||||||
|
* NOTE: no name is written - call from within an array structure.
|
||||||
|
*/
|
||||||
|
public void writeValue(int value) throws IOException
|
||||||
|
{
|
||||||
|
if (stack.peek() == true) out.write(", ");
|
||||||
|
out.write(Integer.toString(value));
|
||||||
|
stack.pop();
|
||||||
|
stack.push(Boolean.TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeValue(Integer value) throws IOException
|
||||||
|
{
|
||||||
|
if (stack.peek() == true) out.write(", ");
|
||||||
|
out.write(value.toString());
|
||||||
|
stack.pop();
|
||||||
|
stack.push(Boolean.TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output a JSON long value.
|
||||||
|
* NOTE: no name is written - call from within an array structure.
|
||||||
|
*/
|
||||||
|
public void writeValue(long value) throws IOException
|
||||||
|
{
|
||||||
|
if (stack.peek() == true) out.write(", ");
|
||||||
|
out.write(Long.toString(value));
|
||||||
|
stack.pop();
|
||||||
|
stack.push(Boolean.TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeValue(Long value) throws IOException
|
||||||
|
{
|
||||||
|
if (stack.peek() == true) out.write(", ");
|
||||||
|
out.write(value.toString());
|
||||||
|
stack.pop();
|
||||||
|
stack.push(Boolean.TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output a JSON number value.
|
||||||
|
* NOTE: no name is written - call from within an array structure.
|
||||||
|
*/
|
||||||
|
public void writeValue(float value) throws IOException
|
||||||
|
{
|
||||||
|
if (stack.peek() == true) out.write(", ");
|
||||||
|
out.write(Float.toString(value));
|
||||||
|
stack.pop();
|
||||||
|
stack.push(Boolean.TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeValue(Float value) throws IOException
|
||||||
|
{
|
||||||
|
if (stack.peek() == true) out.write(", ");
|
||||||
|
out.write(value.toString());
|
||||||
|
stack.pop();
|
||||||
|
stack.push(Boolean.TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output a JSON boolean value.
|
||||||
|
* NOTE: no name is written - call from within an array structure.
|
||||||
|
*/
|
||||||
|
public void writeValue(boolean value) throws IOException
|
||||||
|
{
|
||||||
|
if (stack.peek() == true) out.write(", ");
|
||||||
|
out.write(Boolean.toString(value));
|
||||||
|
stack.pop();
|
||||||
|
stack.push(Boolean.TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeValue(Boolean value) throws IOException
|
||||||
|
{
|
||||||
|
if (stack.peek() == true) out.write(", ");
|
||||||
|
out.write(value.toString());
|
||||||
|
stack.pop();
|
||||||
|
stack.push(Boolean.TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output a JSON null value.
|
||||||
|
* NOTE: no name is written - call from within an array structure.
|
||||||
|
*/
|
||||||
|
public void writeNullValue() throws IOException
|
||||||
|
{
|
||||||
|
if (stack.peek() == true) out.write(", ");
|
||||||
|
out.write("null");
|
||||||
|
stack.pop();
|
||||||
|
stack.push(Boolean.TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output a JSON null value.
|
||||||
|
*/
|
||||||
|
public void writeNullValue(String name) throws IOException
|
||||||
|
{
|
||||||
|
if (stack.peek() == true) out.write(", ");
|
||||||
|
out.write('"');
|
||||||
|
out.write(name);
|
||||||
|
out.write("\": null");
|
||||||
|
stack.pop();
|
||||||
|
stack.push(Boolean.TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Safely encode a JSON string value.
|
||||||
|
* @return encoded string, null is handled and returned as "".
|
||||||
|
*/
|
||||||
|
public static String encodeJSONString(final String s)
|
||||||
|
{
|
||||||
|
if (s == null || s.length() == 0)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder sb = null; // create on demand
|
||||||
|
String enc;
|
||||||
|
char c;
|
||||||
|
int len = s.length();
|
||||||
|
for (int i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
enc = null;
|
||||||
|
c = s.charAt(i);
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case '\\':
|
||||||
|
enc = "\\\\";
|
||||||
|
break;
|
||||||
|
case '"':
|
||||||
|
enc = "\\\"";
|
||||||
|
break;
|
||||||
|
case '/':
|
||||||
|
enc = "\\/";
|
||||||
|
break;
|
||||||
|
case '\b':
|
||||||
|
enc = "\\b";
|
||||||
|
break;
|
||||||
|
case '\t':
|
||||||
|
enc = "\\t";
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
enc = "\\n";
|
||||||
|
break;
|
||||||
|
case '\f':
|
||||||
|
enc = "\\f";
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
enc = "\\r";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (((int)c) >= 0x80)
|
||||||
|
{
|
||||||
|
//encode all non basic latin characters
|
||||||
|
String u = "000" + Integer.toHexString((int)c);
|
||||||
|
enc = "\\u" + u.substring(u.length() - 4);
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enc != null)
|
||||||
|
{
|
||||||
|
if (sb == null)
|
||||||
|
{
|
||||||
|
String soFar = s.substring(0, i);
|
||||||
|
sb = new StringBuilder(i + 8);
|
||||||
|
sb.append(soFar);
|
||||||
|
}
|
||||||
|
sb.append(enc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (sb != null)
|
||||||
|
{
|
||||||
|
sb.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sb == null)
|
||||||
|
{
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,76 @@
|
|||||||
|
package org.alfresco.repo.web.scripts.solr;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.Path;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
|
public class NodeMetaData
|
||||||
|
{
|
||||||
|
private long id;
|
||||||
|
private NodeRef nodeRef;
|
||||||
|
private QName type;
|
||||||
|
private long aclId;
|
||||||
|
private Map<QName, Serializable> properties;
|
||||||
|
private Set<QName> aspects;
|
||||||
|
private Path paths;
|
||||||
|
public long getId()
|
||||||
|
{
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
public void setId(long id)
|
||||||
|
{
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
public NodeRef getNodeRef()
|
||||||
|
{
|
||||||
|
return nodeRef;
|
||||||
|
}
|
||||||
|
public void setNodeRef(NodeRef nodeRef)
|
||||||
|
{
|
||||||
|
this.nodeRef = nodeRef;
|
||||||
|
}
|
||||||
|
public QName getType()
|
||||||
|
{
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
public void setType(QName type)
|
||||||
|
{
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
public long getAclId()
|
||||||
|
{
|
||||||
|
return aclId;
|
||||||
|
}
|
||||||
|
public void setAclId(long aclId)
|
||||||
|
{
|
||||||
|
this.aclId = aclId;
|
||||||
|
}
|
||||||
|
public Map<QName, Serializable> getProperties()
|
||||||
|
{
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
public void setProperties(Map<QName, Serializable> properties)
|
||||||
|
{
|
||||||
|
this.properties = properties;
|
||||||
|
}
|
||||||
|
public Set<QName> getAspects()
|
||||||
|
{
|
||||||
|
return aspects;
|
||||||
|
}
|
||||||
|
public void setAspects(Set<QName> aspects)
|
||||||
|
{
|
||||||
|
this.aspects = aspects;
|
||||||
|
}
|
||||||
|
public Path getPaths()
|
||||||
|
{
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
public void setPaths(Path paths)
|
||||||
|
{
|
||||||
|
this.paths = paths;
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,257 @@
|
|||||||
|
package org.alfresco.repo.web.scripts.solr.test;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.domain.node.ContentDataWithId;
|
||||||
|
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||||
|
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||||
|
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||||
|
import org.alfresco.repo.web.scripts.BaseWebScriptTest;
|
||||||
|
import org.alfresco.service.ServiceRegistry;
|
||||||
|
import org.alfresco.service.cmr.admin.RepoAdminService;
|
||||||
|
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||||
|
import org.alfresco.service.cmr.model.FileFolderService;
|
||||||
|
import org.alfresco.service.cmr.model.FileInfo;
|
||||||
|
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||||
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
|
import org.alfresco.service.cmr.repository.ContentService;
|
||||||
|
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||||
|
import org.alfresco.service.cmr.repository.MLText;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.cmr.repository.Path;
|
||||||
|
import org.alfresco.service.cmr.repository.Period;
|
||||||
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
|
import org.alfresco.util.PropertyMap;
|
||||||
|
import org.alfresco.util.SOLRDeserializer;
|
||||||
|
import org.alfresco.util.SOLRSerializer;
|
||||||
|
|
||||||
|
public class SOLRSerializerTests extends BaseWebScriptTest
|
||||||
|
{
|
||||||
|
static final String SOLR_TEST_MODEL_1_0_URI = "http://www.alfresco.org/model/solrtest/1.0";
|
||||||
|
static final QName TYPE_TEST_OBJECT = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "testobject");
|
||||||
|
static final QName PROP_MLTEXT = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "mlTextProp");
|
||||||
|
static final QName PROP_BOOL = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "boolProp");
|
||||||
|
static final QName PROP_LONG = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "longProp");
|
||||||
|
static final QName PROP_FLOAT = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "floatProp");
|
||||||
|
static final QName PROP_DOUBLE = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "doubleProp");
|
||||||
|
static final QName PROP_DATE = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "dateProp");
|
||||||
|
static final QName PROP_DATETIME = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "dateTimeProp");
|
||||||
|
static final QName PROP_QNAME = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "qnameProp");
|
||||||
|
static final QName PROP_NODEREF = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "nodeRefProp");
|
||||||
|
static final QName PROP_CHILDASSOC = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "childAssocProp");
|
||||||
|
static final QName PROP_ASSOC = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "assocProp");
|
||||||
|
static final QName PROP_PATH = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "pathProp");
|
||||||
|
static final QName PROP_CATEGORY = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "categoryProp");
|
||||||
|
static final QName PROP_LOCALE = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "localeProp");
|
||||||
|
static final QName PROP_PERIOD = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "periodProp");
|
||||||
|
static final QName PROP_ANY = QName.createQName(SOLR_TEST_MODEL_1_0_URI, "anyProp");
|
||||||
|
|
||||||
|
private AuthenticationComponent authenticationComponent;
|
||||||
|
private TransactionService transactionService;
|
||||||
|
private RetryingTransactionHelper txnHelper;
|
||||||
|
private NodeService nodeService;
|
||||||
|
private FileFolderService fileFolderService;
|
||||||
|
private ContentService contentService;
|
||||||
|
private DictionaryService dictionaryService;
|
||||||
|
private RepoAdminService repoAdminService;
|
||||||
|
|
||||||
|
private SOLRSerializer solrSerializer;
|
||||||
|
private SOLRDeserializer solrDeserializer;
|
||||||
|
|
||||||
|
private StoreRef storeRef;
|
||||||
|
private NodeRef rootNodeRef;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUp() throws Exception
|
||||||
|
{
|
||||||
|
ServiceRegistry serviceRegistry = (ServiceRegistry) getServer().getApplicationContext().getBean(ServiceRegistry.SERVICE_REGISTRY);
|
||||||
|
transactionService = serviceRegistry.getTransactionService();
|
||||||
|
txnHelper = transactionService.getRetryingTransactionHelper();
|
||||||
|
fileFolderService = serviceRegistry.getFileFolderService();
|
||||||
|
contentService = serviceRegistry.getContentService();
|
||||||
|
nodeService = serviceRegistry.getNodeService();
|
||||||
|
dictionaryService = serviceRegistry.getDictionaryService();
|
||||||
|
authenticationComponent = (AuthenticationComponent)getServer().getApplicationContext().getBean("authenticationComponent");
|
||||||
|
repoAdminService = (RepoAdminService)getServer().getApplicationContext().getBean("repoAdminService");
|
||||||
|
|
||||||
|
solrSerializer = (SOLRSerializer)getServer().getApplicationContext().getBean("solrSerializer");
|
||||||
|
solrDeserializer = new SOLRDeserializer(dictionaryService);
|
||||||
|
|
||||||
|
authenticationComponent.setSystemUserAsCurrentUser();
|
||||||
|
|
||||||
|
InputStream modelStream = getClass().getClassLoader().getResourceAsStream("solr/solr-test-model.xml");
|
||||||
|
repoAdminService.deployModel(modelStream, "solr-test-model");
|
||||||
|
|
||||||
|
storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, getName() + System.currentTimeMillis());
|
||||||
|
rootNodeRef = nodeService.getRootNode(storeRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
private NodeRef solrNode;
|
||||||
|
private Date date;
|
||||||
|
private MLText mlText;
|
||||||
|
private ChildAssociationRef childAssoc;
|
||||||
|
private AssociationRef assoc;
|
||||||
|
private List<NodeRef> multiCategory;
|
||||||
|
private NodeRef category;
|
||||||
|
|
||||||
|
private static String[] mlOrderable_en = new String[] { "AAAA BBBB", "EEEE FFFF", "II", "KK", "MM", "OO", "QQ", "SS", "UU", "AA", "CC" };
|
||||||
|
|
||||||
|
private static String[] mlOrderable_fr = new String[] { "CCCC DDDD", "GGGG HHHH", "JJ", "LL", "NN", "PP", "RR", "TT", "VV", "BB", "DD" };
|
||||||
|
|
||||||
|
private MLText makeMLText()
|
||||||
|
{
|
||||||
|
return makeMLText(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private MLText makeMLText(int position)
|
||||||
|
{
|
||||||
|
MLText ml = new MLText();
|
||||||
|
ml.addValue(Locale.ENGLISH, mlOrderable_en[position]);
|
||||||
|
ml.addValue(Locale.FRENCH, mlOrderable_fr[position]);
|
||||||
|
return ml;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildTransaction()
|
||||||
|
{
|
||||||
|
PropertyMap props = new PropertyMap();
|
||||||
|
props.put(ContentModel.PROP_NAME, "Container1");
|
||||||
|
NodeRef container = nodeService.createNode(
|
||||||
|
rootNodeRef,
|
||||||
|
ContentModel.ASSOC_CHILDREN,
|
||||||
|
ContentModel.ASSOC_CHILDREN,
|
||||||
|
ContentModel.TYPE_FOLDER,
|
||||||
|
props).getChildRef();
|
||||||
|
|
||||||
|
FileInfo contentInfo = fileFolderService.create(container, "SolrNode", TYPE_TEST_OBJECT);
|
||||||
|
solrNode = contentInfo.getNodeRef();
|
||||||
|
ContentWriter writer = contentService.getWriter(solrNode, ContentModel.PROP_CONTENT, true);
|
||||||
|
writer.putContent("Some Content");
|
||||||
|
|
||||||
|
date = new Date();
|
||||||
|
mlText = makeMLText();
|
||||||
|
childAssoc = new ChildAssociationRef(ContentModel.ASSOC_CHILDREN,
|
||||||
|
new NodeRef("testProtocol", "testID", "abcde"),
|
||||||
|
QName.createQName("testProtocol", "testID"),
|
||||||
|
new NodeRef("testProtocol", "testID", "xyz"));
|
||||||
|
assoc = new AssociationRef(
|
||||||
|
new NodeRef("testProtocol", "testID", "abcde"),
|
||||||
|
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "parts"),
|
||||||
|
new NodeRef("testProtocol", "testID", "xyz"));
|
||||||
|
|
||||||
|
Map<QName, Serializable> properties = new HashMap<QName, Serializable>();
|
||||||
|
properties.put(PROP_BOOL, Boolean.TRUE);
|
||||||
|
properties.put(PROP_LONG, Long.valueOf(42));
|
||||||
|
properties.put(PROP_FLOAT, Float.valueOf(42.0f));
|
||||||
|
properties.put(PROP_DOUBLE, Double.valueOf(42.0));
|
||||||
|
properties.put(PROP_DATE, date);
|
||||||
|
properties.put(PROP_DATETIME, date);
|
||||||
|
properties.put(PROP_NODEREF, container);
|
||||||
|
properties.put(PROP_LOCALE, Locale.ITALY);
|
||||||
|
properties.put(PROP_QNAME, PROP_QNAME);
|
||||||
|
//properties.put(PROP_VERSION, new VersionNumber("1.0"));
|
||||||
|
properties.put(PROP_PERIOD, new Period("period|12"));
|
||||||
|
Path path = new Path();
|
||||||
|
Path.Element element0 = new Path.ChildAssocElement(new ChildAssociationRef(null, null, null, new NodeRef("testProtocol", "testID", "abcde")));
|
||||||
|
path.prepend(element0);
|
||||||
|
properties.put(PROP_PATH, path);
|
||||||
|
properties.put(PROP_ASSOC, assoc);
|
||||||
|
category = new NodeRef("testProtocol", "testID", "cat1");
|
||||||
|
properties.put(PROP_CATEGORY, (Serializable)category);
|
||||||
|
properties.put(PROP_CHILDASSOC, childAssoc);
|
||||||
|
properties.put(PROP_MLTEXT, mlText);
|
||||||
|
|
||||||
|
nodeService.setProperties(solrNode, properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAll()
|
||||||
|
{
|
||||||
|
txnHelper.doInTransaction(new RetryingTransactionCallback<Void>()
|
||||||
|
{
|
||||||
|
public Void execute() throws Throwable
|
||||||
|
{
|
||||||
|
buildTransaction();
|
||||||
|
|
||||||
|
Serializable value = nodeService.getProperty(solrNode, ContentModel.PROP_NAME);
|
||||||
|
Object serialized = solrSerializer.serialize(ContentModel.PROP_NAME, value);
|
||||||
|
Serializable deserialized = solrDeserializer.deserialize(ContentModel.PROP_NAME, serialized);
|
||||||
|
assertEquals(value, deserialized);
|
||||||
|
|
||||||
|
value = nodeService.getProperty(solrNode, PROP_MLTEXT);
|
||||||
|
serialized = solrSerializer.serialize(PROP_MLTEXT, value);
|
||||||
|
deserialized = solrDeserializer.deserialize(PROP_MLTEXT, serialized);
|
||||||
|
assertEquals(value, deserialized);
|
||||||
|
|
||||||
|
value = nodeService.getProperty(solrNode, ContentModel.PROP_CONTENT);
|
||||||
|
assertTrue("Expected ContentDataId, got " + value.getClass().getName(), value instanceof ContentDataWithId);
|
||||||
|
serialized = solrSerializer.serialize(ContentModel.PROP_CONTENT, value);
|
||||||
|
deserialized = solrDeserializer.deserialize(ContentModel.PROP_CONTENT, serialized);
|
||||||
|
assertEquals(value, deserialized);
|
||||||
|
|
||||||
|
value = nodeService.getProperty(solrNode, PROP_BOOL);
|
||||||
|
serialized = solrSerializer.serialize(PROP_BOOL, value);
|
||||||
|
deserialized = solrDeserializer.deserialize(PROP_BOOL, serialized);
|
||||||
|
assertEquals(value, deserialized);
|
||||||
|
|
||||||
|
value = nodeService.getProperty(solrNode, PROP_DATE);
|
||||||
|
assertTrue("Expected Date object, got " + value.getClass().getName(), value instanceof Date);
|
||||||
|
serialized = solrSerializer.serialize(PROP_DATE, value);
|
||||||
|
deserialized = solrDeserializer.deserialize(PROP_DATE, serialized);
|
||||||
|
assertEquals(value, deserialized);
|
||||||
|
|
||||||
|
value = nodeService.getProperty(solrNode, PROP_DATETIME);
|
||||||
|
assertTrue("Expected Date object, got " + value.getClass().getName(), value instanceof Date);
|
||||||
|
serialized = solrSerializer.serialize(PROP_DATETIME, value);
|
||||||
|
deserialized = solrDeserializer.deserialize(PROP_DATETIME, serialized);
|
||||||
|
assertEquals(value, deserialized);
|
||||||
|
|
||||||
|
value = nodeService.getProperty(solrNode, PROP_DOUBLE);
|
||||||
|
assertTrue("Expected Double object, got " + value.getClass().getName(), value instanceof Double);
|
||||||
|
serialized = solrSerializer.serialize(PROP_DATETIME, value);
|
||||||
|
deserialized = solrDeserializer.deserialize(PROP_DATETIME, serialized);
|
||||||
|
assertEquals(value, deserialized);
|
||||||
|
|
||||||
|
value = nodeService.getProperty(solrNode, PROP_FLOAT);
|
||||||
|
assertTrue("Expected Float object, got " + value.getClass().getName(), value instanceof Float);
|
||||||
|
serialized = solrSerializer.serialize(PROP_FLOAT, value);
|
||||||
|
deserialized = solrDeserializer.deserialize(PROP_FLOAT, serialized);
|
||||||
|
assertEquals(value, deserialized);
|
||||||
|
|
||||||
|
value = nodeService.getProperty(solrNode, PROP_LONG);
|
||||||
|
assertTrue("Expected Long object, got " + value.getClass().getName(), value instanceof Long);
|
||||||
|
serialized = solrSerializer.serialize(PROP_LONG, value);
|
||||||
|
deserialized = solrDeserializer.deserialize(PROP_LONG, serialized);
|
||||||
|
assertEquals(value, deserialized);
|
||||||
|
|
||||||
|
value = nodeService.getProperty(solrNode, PROP_CHILDASSOC);
|
||||||
|
serialized = solrSerializer.serialize(PROP_CHILDASSOC, value);
|
||||||
|
deserialized = solrDeserializer.deserialize(PROP_CHILDASSOC, serialized);
|
||||||
|
assertEquals(value, deserialized);
|
||||||
|
|
||||||
|
value = nodeService.getProperty(solrNode, PROP_ASSOC);
|
||||||
|
serialized = solrSerializer.serialize(PROP_ASSOC, value);
|
||||||
|
deserialized = solrDeserializer.deserialize(PROP_ASSOC, serialized);
|
||||||
|
assertEquals(value, deserialized);
|
||||||
|
|
||||||
|
value = nodeService.getProperty(solrNode, PROP_CATEGORY);
|
||||||
|
serialized = solrSerializer.serialize(PROP_ASSOC, value);
|
||||||
|
deserialized = solrDeserializer.deserialize(PROP_ASSOC, serialized);
|
||||||
|
assertEquals(value, deserialized);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -1,108 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
|
||||||
*
|
|
||||||
* This file is part of Alfresco
|
|
||||||
*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
package org.alfresco.repo.web.util.auth;
|
|
||||||
|
|
||||||
import org.alfresco.service.cmr.security.PermissionService;
|
|
||||||
import org.alfresco.util.ParameterCheck;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper to process username / password pairs passed to the remote tier
|
|
||||||
*
|
|
||||||
* Identifies whether username / password is a ticket.
|
|
||||||
*
|
|
||||||
* Is ticket, if one of the following is true:
|
|
||||||
*
|
|
||||||
* a) Username == "ROLE_TICKET" (in any case)
|
|
||||||
* b) Username is not specified (i.e. null)
|
|
||||||
* c) Username is zero length
|
|
||||||
*/
|
|
||||||
public class Authorization
|
|
||||||
{
|
|
||||||
public static String TICKET_USERID = PermissionService.ROLE_PREFIX + "TICKET";
|
|
||||||
|
|
||||||
private String username;
|
|
||||||
private String password;
|
|
||||||
private String ticket;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct
|
|
||||||
*
|
|
||||||
* @param authorization
|
|
||||||
*/
|
|
||||||
public Authorization(String authorization)
|
|
||||||
{
|
|
||||||
ParameterCheck.mandatoryString("authorization", authorization);
|
|
||||||
String[] parts = authorization.split(":");
|
|
||||||
if (parts.length == 1)
|
|
||||||
{
|
|
||||||
setUser(null, parts[0]);
|
|
||||||
}
|
|
||||||
else if (parts.length == 2)
|
|
||||||
{
|
|
||||||
setUser(parts[0], parts[1]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException("authorization does not consist of username and password");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct
|
|
||||||
*
|
|
||||||
* @param username
|
|
||||||
* @param password
|
|
||||||
*/
|
|
||||||
public Authorization(String username, String password)
|
|
||||||
{
|
|
||||||
setUser(username, password);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setUser(String username, String password)
|
|
||||||
{
|
|
||||||
this.username = username;
|
|
||||||
this.password = password;
|
|
||||||
if (username == null || username.length() == 0 || username.equalsIgnoreCase(TICKET_USERID))
|
|
||||||
{
|
|
||||||
|
|
||||||
this.ticket = password;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUserName()
|
|
||||||
{
|
|
||||||
return username;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPassword()
|
|
||||||
{
|
|
||||||
return password;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isTicket()
|
|
||||||
{
|
|
||||||
return ticket != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTicket()
|
|
||||||
{
|
|
||||||
return ticket;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,96 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
|
||||||
*
|
|
||||||
* This file is part of Alfresco
|
|
||||||
*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
package org.alfresco.repo.web.util.auth;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test Authorization
|
|
||||||
*/
|
|
||||||
public class AuthorizationTest extends TestCase
|
|
||||||
{
|
|
||||||
private static String USER = "user";
|
|
||||||
private static String PASSWORD = "pass";
|
|
||||||
|
|
||||||
public void testInvalidAuthorization()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
new Authorization(null);
|
|
||||||
fail();
|
|
||||||
}
|
|
||||||
catch(IllegalArgumentException e)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
new Authorization("username:password:invalid");
|
|
||||||
fail();
|
|
||||||
}
|
|
||||||
catch(IllegalArgumentException e)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAuthorization()
|
|
||||||
{
|
|
||||||
Authorization auth1 = new Authorization(USER, PASSWORD);
|
|
||||||
assertUserPass(USER, PASSWORD, auth1);
|
|
||||||
Authorization auth2 = new Authorization("", PASSWORD);
|
|
||||||
assertTicket("", PASSWORD, auth2);
|
|
||||||
Authorization auth3 = new Authorization(null, PASSWORD);
|
|
||||||
assertTicket(null, PASSWORD, auth3);
|
|
||||||
Authorization auth4 = new Authorization(Authorization.TICKET_USERID, PASSWORD);
|
|
||||||
assertTicket(Authorization.TICKET_USERID, PASSWORD, auth4);
|
|
||||||
Authorization auth5 = new Authorization(Authorization.TICKET_USERID.toLowerCase(), PASSWORD);
|
|
||||||
assertTicket(Authorization.TICKET_USERID.toLowerCase(), PASSWORD, auth5);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testUserPass()
|
|
||||||
{
|
|
||||||
Authorization auth1 = new Authorization(USER + ":" + PASSWORD);
|
|
||||||
assertUserPass(USER, PASSWORD, auth1);
|
|
||||||
Authorization auth2 = new Authorization(":" + PASSWORD);
|
|
||||||
assertTicket("", PASSWORD, auth2);
|
|
||||||
Authorization auth3 = new Authorization(PASSWORD);
|
|
||||||
assertTicket(null, PASSWORD, auth3);
|
|
||||||
Authorization auth4 = new Authorization(Authorization.TICKET_USERID + ":" + PASSWORD);
|
|
||||||
assertTicket(Authorization.TICKET_USERID, PASSWORD, auth4);
|
|
||||||
Authorization auth5 = new Authorization(Authorization.TICKET_USERID.toLowerCase() + ":" + PASSWORD);
|
|
||||||
assertTicket(Authorization.TICKET_USERID.toLowerCase(), PASSWORD, auth5);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertUserPass(String user, String pass, Authorization auth)
|
|
||||||
{
|
|
||||||
assertEquals(user, auth.getUserName());
|
|
||||||
assertEquals(pass, auth.getPassword());
|
|
||||||
assertFalse(auth.isTicket());
|
|
||||||
assertNull(auth.getTicket());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertTicket(String user, String pass, Authorization auth)
|
|
||||||
{
|
|
||||||
assertEquals(user, auth.getUserName());
|
|
||||||
assertEquals(pass, auth.getPassword());
|
|
||||||
assertTrue(auth.isTicket());
|
|
||||||
assertEquals(pass, auth.getTicket());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Reference in New Issue
Block a user