<bean id="springSecurityFilterChain"
class="org.springframework.security.web.FilterChainProxy">
<sec:filter-chain-map path-type="ant">
- <!-- Exclude the "PublishedResourcesServlet" paths from AuthN and AuthZ. Let's us publish resources with anonymous access. -->
- <!--
- <sec:filter-chain pattern="/articles/published/**"
- filters="none"/>
- -->
- <sec:filter-chain pattern="/articles/*/*/published"
+ <!-- Exclude the resource path to public items' content from AuthN and AuthZ. Let's us publish resources with anonymous access. -->
+ <sec:filter-chain pattern="/articles/*/*/content"
filters="none"/>
<sec:filter-chain pattern="/**"
filters="securityContextPersistenceFilter,basicAuthenticationFilter,logoutFilter,exTranslationFilter,filterInvocationInterceptor"/>
<servlet-name>Resteasy</servlet-name>\r
<url-pattern>/*</url-pattern>\r
</servlet-mapping>\r
- \r
- <servlet>\r
- <servlet-name>PublishedResourcesServlet</servlet-name>\r
- <servlet-class>\r
- org.collectionspace.services.common.servlet.PublishedResourcesServlet\r
- </servlet-class>\r
- </servlet> \r
- <servlet-mapping>\r
- <servlet-name>PublishedResourcesServlet</servlet-name>\r
- <url-pattern>/published/*</url-pattern>\r
- </servlet-mapping>\r
\r
</web-app>\r
targetNamespace="http://collectionspace.org/article/"
version="0.1">
- <xs:element name="articleNumber" type="xs:string" /> <!-- An ID for the article (different than the CSID) -->
- <xs:element name="articleContentName" type="xs:string" />
- <xs:element name="articleContentCsid" type="xs:string" /> <!-- The backend repository ID of the article's content -->
- <xs:element name="articleContentUrl" type="xs:string" /> <!-- The publicly accessible URL of the article's content -->
- <xs:element name="articleJobId" type="xs:string" /> <!-- The asynch job ID -if any -->
- <xs:element name="articleSource" type="xs:string" /> <!-- The name of the service/resource that was used to create the article. -->
- <xs:element name="accessExpirationDate" type="xs:dateTime" /> <!-- When the article is no longer available for access -->
- <xs:element name="accessedCount" type="xs:integer" /> <!-- How many times the article has been accessed. -->
- <xs:element name="accessedCountLimit" type="xs:integer" /> <!-- The maximum times the article can be accessed. -->
+ <xs:element name="articleNumber" type="xs:string" /> <!-- An identifier for the article (different than the CSID) -->
+ <xs:element name="articleContentName" type="xs:string" /> <!-- A name for the article's content -->
+ <xs:element name="articleContentRepositoryId" type="xs:string" /> <!-- The backend repository ID of the article's content -->
+ <xs:element name="articleContentUrl" type="xs:string" /> <!-- The publicly accessible URL of the article's content -->
+ <xs:element name="articleJobId" type="xs:string" /> <!-- The asynch job ID -if any -->
+ <xs:element name="articleSource" type="xs:string" /> <!-- The name of the service/resource that was used to create the article. -->
+ <xs:element name="accessExpirationDate" type="xs:dateTime" /> <!-- When the article is no longer available for access -->
+ <xs:element name="accessedCount" type="xs:integer" /> <!-- How many times the article has been accessed. -->
+ <xs:element name="accessedCountLimit" type="xs:integer" /> <!-- The maximum times the article can be accessed. -->
</xs:schema>
public static final String SERVICE_PATH = "/" + SERVICE_PATH_COMPONENT;
public static final String SERVICE_PATH_PROXY = SERVICE_PATH + "/";
public static final String SERVICE_PAYLOAD_NAME = SERVICE_NAME;
- public static final String SERVICE_COMMON_PART_NAME = SERVICE_NAME + PART_LABEL_SEPARATOR + PART_COMMON_LABEL;
+ public static final String SERVICE_COMMON_PART_NAME = SERVICE_NAME + PART_LABEL_SEPARATOR + PART_COMMON_LABEL;
+
+ public static final String PUBLICITEMS_CONTENT_SUFFIX = "content";
/* (non-Javadoc)
* @see org.collectionspace.services.client.AbstractServiceClientImpl#getServicePathComponent()
public interface ArticlesCommonJAXBSchema {
final static String ARTICLE_NUMBER = "articleNumber";
- final static String ARTICLE_CONTENT_CSID = "articleContentCsid";
+ final static String ARTICLE_CONTENT_NAME = "articleContentName";
+ final static String ARTICLE_CONTENT_REPO_ID = "articleContentRepositoryId";
+ final static String ARTICLE_CONTENT_URL = "articleContentUrl";
final static String ARTICLE_JOB_ID = "articleJobId";
final static String ARTICLE_SOURCE = "articleSource";
- final static String ARTICLE_PUBLISHER = "articlePublisher";
final static String ARTICLE_ACCESS_EXPIRATION_DATE = "accessExpirationDate";
final static String ARTICLE_ACCESSED_COUNT = "accessedCount";
- final static String ARTICLE_ACCESS_COUNT_LIMIT = "accessCountLimit";
+ final static String ARTICLE_ACCESSED_COUNT_LIMIT = "accesseedCountLimit";
}
\ No newline at end of file
<xs:element name="articles_common">
<xs:complexType>
<xs:sequence>
- <xs:element name="articleNumber" type="xs:string" /> <!-- An ID for the article (different than the CSID) -->
- <xs:element name="articleContentName" type="xs:string" />
- <xs:element name="articleContentCsid" type="xs:string" /> <!-- The URL of the article's content -->
- <xs:element name="articleContentUrl" type="xs:string" /> <!-- The URL of the article's content -->
- <xs:element name="articleJobId" type="xs:string" /> <!-- The asynch job ID -if any -->
- <xs:element name="articleSource" type="xs:string" /> <!-- The name of the service/resource that was used to create the article. -->
- <xs:element name="accessExpirationDate" type="xs:dateTime" /> <!-- When the article is no longer available for access -->
- <xs:element name="accessedCount" type="xs:integer" /> <!-- How many times the article has been accessed. -->
- <xs:element name="accessedCountLimit" type="xs:integer" /> <!-- The maximum times the article can be accessed. -->
+ <xs:element name="articleNumber" type="xs:string" /> <!-- An identifier for the article (different than the CSID) -->
+ <xs:element name="articleContentName" type="xs:string" /> <!-- A name for the article's content -->
+ <xs:element name="articleContentRepositoryId" type="xs:string" /> <!-- The backend repository ID of the article's content -->
+ <xs:element name="articleContentUrl" type="xs:string" /> <!-- The publicly accessible URL of the article's content -->
+ <xs:element name="articleJobId" type="xs:string" /> <!-- The asynch job ID -if any -->
+ <xs:element name="articleSource" type="xs:string" /> <!-- The name of the service/resource that was used to create the article. -->
+ <xs:element name="accessExpirationDate" type="xs:dateTime" /> <!-- When the article is no longer available for access -->
+ <xs:element name="accessedCount" type="xs:integer" /> <!-- How many times the article has been accessed. -->
+ <xs:element name="accessedCountLimit" type="xs:integer" /> <!-- The maximum times the article can be accessed. -->
</xs:sequence>
</xs:complexType>
</xs:element>
*/
package org.collectionspace.services.article.nuxeo;
+import org.collectionspace.services.ArticlesCommonJAXBSchema;
import org.collectionspace.services.article.ArticlesCommon;
+import org.collectionspace.services.client.ArticleClient;
+import org.collectionspace.services.common.document.DocumentWrapper;
import org.collectionspace.services.nuxeo.client.java.DocHandlerBase;
+import org.nuxeo.ecm.core.api.DocumentModel;
/** ArticleDocumentModelHandler
* $LastChangedRevision$
*/
public class ArticleDocumentModelHandler
extends DocHandlerBase<ArticlesCommon> {
+
+ @Override
+ public void fillAllParts(DocumentWrapper<DocumentModel> wrapDoc, Action action) throws Exception {
+ //
+ // Call our parent's implementation first to fill out most of the document model properties
+ //
+ super.fillAllParts(wrapDoc, action);
+
+ //
+ // Since we didn't know the CSID when we created the publicly accessible URL we need to
+ // add it now.
+ //
+ DocumentModel documentModel = wrapDoc.getWrappedObject();
+ String url = (String) documentModel.getProperty(ArticleClient.SERVICE_COMMON_PART_NAME,
+ ArticlesCommonJAXBSchema.ARTICLE_CONTENT_URL);
+ url = url.replace(ArticleClient.CSID_PATH_PARAM_VAR, documentModel.getName());
+ documentModel.setProperty(ArticleClient.SERVICE_COMMON_PART_NAME,
+ ArticlesCommonJAXBSchema.ARTICLE_CONTENT_URL, url);
+ }
}
*/
public interface CollectionSpaceClient<CLT, REQUEST_TYPE, RESPONSE_TYPE, P extends CollectionSpaceProxy<CLT>> {
+ public final static String CSID_PATH_PARAM_VAR = "{csid}";
public final static String COLLECTIONSPACE_CORE_SCHEMA = "collectionspace_core";
public final static String COLLECTIONSPACE_CORE_TENANTID = "tenantId";
<service:xpath>articleNumber</service:xpath>
</service:ListResultField>
<service:ListResultField>
- <service:element>articleContentCsid</service:element>
- <service:xpath>articleContentCsid</service:xpath>
+ <service:element>articleSource</service:element>
+ <service:xpath>articleSource</service:xpath>
</service:ListResultField>
+ <service:ListResultField>
+ <service:element>articleContentUrl</service:element>
+ <service:xpath>articleContentUrl</service:xpath>
+ </service:ListResultField>
</service:ListResultsFields>
</service:params>
</service:DocHandlerParams>
}
@GET
- @Path("/{csid}/{tenantId}/published")
+ @Path("/{csid}/{tenantId}/" + ArticleClient.PUBLICITEMS_CONTENT_SUFFIX) // "content"
public Response getPublishedResource(
@Context Request request,
@Context UriInfo uriInfo,
//
// Get the repository blob ID and retrieve the content as a stream
//
- String blobContentCsid = articlesCommon.getArticleContentCsid();
+ String blobContentCsid = articlesCommon.getArticleContentRepositoryId();
StringBuffer outMimeType = new StringBuffer();
BlobOutput blobOutput = NuxeoBlobUtils.getBlobOutput(ctx, getRepositoryClient(ctx), blobContentCsid, outMimeType);
InputStream contentStream = blobOutput.getBlobInputStream();
result = new ArticlesCommon(); // If they passed in null, we'll create a new instance
}
- String publishingService = parentCtx.getServiceName(); // Overrides any existing value
- result.setArticleSource(publishingService);
+ String articleSource = result.getArticleSource();
+ if (articleSource == null || articleSource.trim().isEmpty()) {
+ String publishingService = parentCtx.getServiceName(); // Overrides any existing value
+ result.setArticleSource(publishingService);
+ }
+
+ String publicUrl = String.format("%s%s/%s/%s/%s", // e.g., http://{base url}/articles/{csid}/{tenant ID}/content
+ uriInfo.getBaseUri().toString(), // the base part of the URL
+ ArticleClient.SERVICE_NAME, // the base service path to the Article service
+ ArticleClient.CSID_PATH_PARAM_VAR, // the {csid} param part that will be filled in later in ArticleDocumentModelHandler.fillAllParts() method
+ parentCtx.getTenantId(), // the tenant ID part
+ ArticleClient.PUBLICITEMS_CONTENT_SUFFIX); // the final "content" suffix
+ result.setArticleContentUrl(publicUrl);
- String articleContentUrl = "the public url goes here";
- result.setArticleContentUrl(articleContentUrl);
-
return result;
}
BlobsCommon blobsCommon = NuxeoBlobUtils.createBlobInRepository(parentCtx, repositoryClient, inputStream, streamName);
articlesCommon = setArticlesCommonMetadata(articlesCommon, uriInfo, parentCtx);
- articlesCommon.setArticleContentCsid(blobsCommon.getRepositoryId());
+ articlesCommon.setArticleContentRepositoryId(blobsCommon.getRepositoryId());
articlesCommon.setArticleContentName(streamName);
PoxPayloadOut poxPayloadOut = new PoxPayloadOut(ArticleClient.SERVICE_PAYLOAD_NAME);
/*
* Publishes the report to the Articles service. The response is a URI to the corresponding Article resource instance in
* the form of /articles/{csid}.
- * To access the contents of the report use a form like /articles/published/{csid}?tid={tenant ID}. For example,
- * http://localhost:8180/cspace-services/articles/published/2991da78-6001-4f34-b02c?tid=1
+ * To access the contents of the report use a form like /articles/{csid}/{tenantId}/content. For example,
+ * http://localhost:8180/cspace-services/articles/2991da78-6001-4f34-b02/1/content
*/
@POST
@Path("{csid}/publish")