use of org.alfresco.service.cmr.repository.ContentReader in project alfresco-remote-api by Alfresco.
the class TestCMIS method testCreationDate.
/**
* MNT-12680
* The creation date of version should be the same as creation date of the original node
* @throws Exception
*/
@Test
public void testCreationDate() throws Exception {
// create a site
final TestNetwork network1 = getTestFixture().getRandomNetwork();
String username = "user" + System.currentTimeMillis();
PersonInfo personInfo = new PersonInfo(username, username, username, "password", null, null, null, null, null, null, null);
TestPerson person1 = network1.createUser(personInfo);
String person1Id = person1.getId();
final String siteName = "site" + System.currentTimeMillis();
TenantUtil.runAsUserTenant(new TenantRunAsWork<NodeRef>() {
@Override
public NodeRef doWork() throws Exception {
SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PUBLIC);
final TestSite site = network1.createSite(siteInfo);
final NodeRef resNode = repoService.createDocument(site.getContainerNodeRef("documentLibrary"), "testdoc.txt", "Test Doc1 Title", "Test Doc1 Description", "Test Content");
return resNode;
}
}, person1Id, network1.getId());
// create a document
publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id));
CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_10, AlfrescoObjectFactoryImpl.class.getName());
AlfrescoFolder docLibrary = (AlfrescoFolder) cmisSession.getObjectByPath("/Sites/" + siteName + "/documentLibrary");
Map<String, String> properties = new HashMap<String, String>();
{
properties.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT);
properties.put(PropertyIds.NAME, "mydoc-" + GUID.generate() + ".txt");
}
ContentStreamImpl fileContent = new ContentStreamImpl();
{
ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt"));
writer.putContent("some content");
ContentReader reader = writer.getReader();
fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN);
fileContent.setStream(reader.getContentInputStream());
}
Document autoVersionedDoc = docLibrary.createDocument(properties, fileContent, VersioningState.MAJOR);
String objectId = autoVersionedDoc.getId();
String bareObjectId = stripCMISSuffix(objectId);
// create versions
for (int i = 0; i < 3; i++) {
Document doc1 = (Document) cmisSession.getObject(bareObjectId);
ObjectId pwcId = doc1.checkOut();
Document pwc = (Document) cmisSession.getObject(pwcId.getId());
ContentStreamImpl contentStream = new ContentStreamImpl();
{
ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt"));
writer.putContent(GUID.generate());
ContentReader reader = writer.getReader();
contentStream.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN);
contentStream.setStream(reader.getContentInputStream());
}
pwc.checkIn(true, Collections.EMPTY_MAP, contentStream, "checkin " + i);
}
GregorianCalendar cDateFirst = cmisSession.getAllVersions(bareObjectId).get(0).getCreationDate();
GregorianCalendar cDateSecond = cmisSession.getAllVersions(bareObjectId).get(2).getCreationDate();
if (cDateFirst.before(cDateSecond) || cDateFirst.after(cDateSecond)) {
fail("The creation date of version should be the same as creation date of the original node");
}
}
use of org.alfresco.service.cmr.repository.ContentReader in project alfresco-remote-api by Alfresco.
the class RepoStore method getDocument.
/* (non-Javadoc)
* @see org.alfresco.web.scripts.Store#getDescriptionDocument(java.lang.String)
*/
public InputStream getDocument(final String documentPath) throws IOException {
return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<InputStream>() {
public InputStream doWork() throws Exception {
return retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<InputStream>() {
public InputStream execute() throws Exception {
NodeRef nodeRef = findNodeRef(documentPath);
if (nodeRef == null) {
throw new IOException("Document " + documentPath + " does not exist.");
}
ContentReader reader = contentService.getReader(nodeRef, ContentModel.PROP_CONTENT);
if (reader == null || !reader.exists()) {
throw new IOException("Failed to read content at " + documentPath + " (content reader does not exist)");
}
return reader.getContentInputStream();
}
}, true, false);
}
}, AuthenticationUtil.getSystemUserName());
}
use of org.alfresco.service.cmr.repository.ContentReader in project alfresco-remote-api by Alfresco.
the class RemoteFileFolderLoaderTest method testLoad_15_16bytes.
/**
* Load 15 files; 1K size; 1 document sample; force binary storage
*/
@SuppressWarnings("unchecked")
public void testLoad_15_16bytes() throws Exception {
JSONObject body = new JSONObject();
body.put(FileFolderLoaderPost.KEY_FOLDER_PATH, loadHomePath);
body.put(FileFolderLoaderPost.KEY_MIN_FILE_SIZE, 16L);
body.put(FileFolderLoaderPost.KEY_MAX_FILE_SIZE, 16L);
body.put(FileFolderLoaderPost.KEY_MAX_UNIQUE_DOCUMENTS, 1L);
body.put(FileFolderLoaderPost.KEY_FORCE_BINARY_STORAGE, Boolean.TRUE);
Response response = null;
try {
AuthenticationUtil.pushAuthentication();
AuthenticationUtil.setFullyAuthenticatedUser("maggi");
response = sendRequest(new PostRequest(URL, body.toString(), "application/json"), Status.STATUS_OK, "maggi");
} finally {
AuthenticationUtil.popAuthentication();
}
assertEquals("{\"count\":100}", response.getContentAsString());
// Check file(s)
assertEquals(100, nodeService.countChildAssocs(loadHomeNodeRef, true));
// Consistent binary text
String contentUrlCheck = SpoofedTextContentReader.createContentUrl(Locale.ENGLISH, 0L, 16L);
ContentReader readerCheck = new SpoofedTextContentReader(contentUrlCheck);
String textCheck = readerCheck.getContentString();
// Size should be default
List<FileInfo> fileInfos = fileFolderService.list(loadHomeNodeRef);
for (FileInfo fileInfo : fileInfos) {
NodeRef fileNodeRef = fileInfo.getNodeRef();
ContentReader reader = fileFolderService.getReader(fileNodeRef);
// Expect storage in store
assertTrue(reader.getContentUrl().startsWith(FileContentStore.STORE_PROTOCOL));
// Check text
String text = reader.getContentString();
assertEquals("Text not the same.", textCheck, text);
}
}
use of org.alfresco.service.cmr.repository.ContentReader in project alfresco-remote-api by Alfresco.
the class RemoteFileFolderLoaderTest method testLoad_15_default.
/**
* Load 15 files with default sizes
*/
@SuppressWarnings("unchecked")
public void testLoad_15_default() throws Exception {
JSONObject body = new JSONObject();
body.put(FileFolderLoaderPost.KEY_FOLDER_PATH, loadHomePath);
body.put(FileFolderLoaderPost.KEY_FILE_COUNT, 15);
body.put(FileFolderLoaderPost.KEY_FILES_PER_TXN, 10);
Response response = null;
try {
AuthenticationUtil.pushAuthentication();
AuthenticationUtil.setFullyAuthenticatedUser("hhoudini");
response = sendRequest(new PostRequest(URL, body.toString(), "application/json"), Status.STATUS_OK, "hhoudini");
} finally {
AuthenticationUtil.popAuthentication();
}
assertEquals("{\"count\":15}", response.getContentAsString());
// Check file(s)
assertEquals(15, nodeService.countChildAssocs(loadHomeNodeRef, true));
// Size should be default
List<FileInfo> fileInfos = fileFolderService.list(loadHomeNodeRef);
for (FileInfo fileInfo : fileInfos) {
NodeRef fileNodeRef = fileInfo.getNodeRef();
ContentReader reader = fileFolderService.getReader(fileNodeRef);
// Expect spoofing by default
assertTrue(reader.getContentUrl().startsWith(FileContentStore.SPOOF_PROTOCOL));
assertTrue("Default file size not correct: " + reader, FileFolderLoaderPost.DEFAULT_MIN_FILE_SIZE < reader.getSize() && reader.getSize() < FileFolderLoaderPost.DEFAULT_MAX_FILE_SIZE);
// Check creator
assertEquals("hhoudini", nodeService.getProperty(fileNodeRef, ContentModel.PROP_CREATOR));
// We also expect the default language description to be present
String description = (String) nodeService.getProperty(fileNodeRef, ContentModel.PROP_DESCRIPTION);
assertNotNull("No description", description);
assertEquals("Description length incorrect: \"" + description + "\"", 128L, description.getBytes("UTF-8").length);
}
}
use of org.alfresco.service.cmr.repository.ContentReader in project alfresco-remote-api by Alfresco.
the class HttpRangeProcessor method processMultiRange.
/**
* Process multiple ranges.
*
* @param res HttpServletResponse
* @param range Range header value
* @param ref NodeRef to the content for streaming
* @param property Content Property for the content
* @param mimetype Mimetype of the content
* @param userAgent User Agent of the caller
*
* @return true if processed range, false otherwise
*/
private boolean processMultiRange(Object res, String range, NodeRef ref, QName property, String mimetype, String userAgent) throws IOException {
final Log logger = getLogger();
// Handle either HttpServletResponse or WebScriptResponse
HttpServletResponse httpServletResponse = null;
WebScriptResponse webScriptResponse = null;
if (res instanceof HttpServletResponse) {
httpServletResponse = (HttpServletResponse) res;
} else if (res instanceof WebScriptResponse) {
webScriptResponse = (WebScriptResponse) res;
}
if (httpServletResponse == null && webScriptResponse == null) {
// Unknown response object type
return false;
}
// return the sets of bytes as requested in the content-range header
// the response will be formatted as multipart/byteranges media type message
/* Examples of byte-ranges-specifier values (assuming an entity-body of length 10000):
- The first 500 bytes (byte offsets 0-499, inclusive): bytes=0-499
- The second 500 bytes (byte offsets 500-999, inclusive):
bytes=500-999
- The final 500 bytes (byte offsets 9500-9999, inclusive):
bytes=-500
- Or bytes=9500-
- The first and last bytes only (bytes 0 and 9999): bytes=0-0,-1
- Several legal but not canonical specifications of byte offsets 500-999, inclusive:
bytes=500-600,601-999
bytes=500-700,601-999 */
boolean processedRange = false;
// get the content reader
ContentReader reader = contentService.getReader(ref, property);
final List<Range> ranges = new ArrayList<Range>(8);
long entityLength = reader.getSize();
for (StringTokenizer t = new StringTokenizer(range, ", "); t.hasMoreTokens(); ) /**/
{
try {
ranges.add(Range.constructRange(t.nextToken(), mimetype, entityLength));
} catch (IllegalArgumentException err) {
if (getLogger().isDebugEnabled())
getLogger().debug("Failed to parse range header - returning 416 status code: " + err.getMessage());
if (httpServletResponse != null) {
httpServletResponse.setStatus(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
httpServletResponse.setHeader(HEADER_CONTENT_RANGE, "\"*\"");
httpServletResponse.getOutputStream().close();
} else if (webScriptResponse != null) {
webScriptResponse.setStatus(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
webScriptResponse.setHeader(HEADER_CONTENT_RANGE, "\"*\"");
webScriptResponse.getOutputStream().close();
}
return true;
}
}
if (ranges.size() != 0) {
// merge byte ranges if possible - IE handles this well, FireFox not so much
if (userAgent == null || userAgent.indexOf("MSIE ") != -1) {
Collections.sort(ranges);
for (int i = 0; i < ranges.size() - 1; i++) {
Range first = ranges.get(i);
Range second = ranges.get(i + 1);
if (first.end + 1 >= second.start) {
if (logger.isDebugEnabled())
logger.debug("Merging byte range: " + first + " with " + second);
if (first.end < second.end) {
// merge second range into first
first.end = second.end;
}
// else we simply discard the second range - it is contained within the first
// delete second range
ranges.remove(i + 1);
// reset loop index
i--;
}
}
}
// calculate response content length
long length = MULTIPART_BYTERANGES_BOUNDRY_END.length() + 2;
for (Range r : ranges) {
length += r.getLength();
}
// output headers as we have at least one range to process
OutputStream os = null;
if (httpServletResponse != null) {
httpServletResponse.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
httpServletResponse.setHeader(HEADER_CONTENT_TYPE, MULTIPART_BYTERANGES_HEADER);
httpServletResponse.setHeader(HEADER_CONTENT_LENGTH, Long.toString(length));
os = httpServletResponse.getOutputStream();
} else if (webScriptResponse != null) {
webScriptResponse.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
webScriptResponse.setHeader(HEADER_CONTENT_TYPE, MULTIPART_BYTERANGES_HEADER);
webScriptResponse.setHeader(HEADER_CONTENT_LENGTH, Long.toString(length));
os = webScriptResponse.getOutputStream();
}
InputStream is = null;
try {
for (Range r : ranges) {
if (logger.isDebugEnabled())
logger.debug("Processing: " + r.getContentRange());
try {
// output the header bytes for the range
if (os instanceof ServletOutputStream)
r.outputHeader((ServletOutputStream) os);
// output the binary data for the range
// need a new reader for each new InputStream
is = contentService.getReader(ref, property).getContentInputStream();
streamRangeBytes(r, is, os, 0L);
is.close();
is = null;
// section marker and flush stream
if (os instanceof ServletOutputStream)
((ServletOutputStream) os).println();
os.flush();
} catch (IOException err) {
if (getLogger().isDebugEnabled())
getLogger().debug("Unable to process multiple range due to IO Exception: " + err.getMessage());
throw err;
}
}
} finally {
if (is != null) {
is.close();
}
}
// end marker
if (os instanceof ServletOutputStream)
((ServletOutputStream) os).println(MULTIPART_BYTERANGES_BOUNDRY_END);
os.close();
processedRange = true;
}
return processedRange;
}
Aggregations