顯示具有 Alfresco 標籤的文章。 顯示所有文章
顯示具有 Alfresco 標籤的文章。 顯示所有文章

星期日, 8月 17, 2014

[Alfresco] 上傳大檔的相關問題筆記


先前處理alfresco上傳的議題
  1. Heap Size issue (Need to increase that) 
  2. JVM memory allocation 
  3. session time out (It will take more time to write the data on created content so need to make sure session timeout does not happens)

星期五, 6月 13, 2014

[Alfresco] CMIS上傳無法超過4MB

怕以後升級會遇到,先筆記下來
Alfresco versions: 4.2.d (community), 4.2.0 (enterprise).
In the file repository.properties (under WEB-INF/classes/) you can change three properties:
webscripts.tempDirectoryName=WebScripts

# 4mb

webscripts.memoryThreshold=4194304

# 4gb

webscripts.setMaxContentSize=4294967296
The first property webscripts.tempDirectoryName specify the name of subdirectory inside default Temp Dir where Webscript and CMIS will create the temp file when necessary.
The second property webscripts.memoryThreshold specify the threshold value after that Webscript and CMIS use a Temp File to store the content upload instead use of memory buffer.
The third property webscripts.setMaxContentSize specify the maximum size allowed in Alfresco Webscript to manage content file.

星期日, 4月 14, 2013

[Alfresco] 如何取得webscript的參數

這篇記錄如何從webscript取得QueryString、Path parameter of URL與Post body

QueryString
<url>/people/search/email?filter={email}</url>
function main()
{
   var filter = args["filter"];
}


Path parameter
<url>/person/{userName}</url>
function main()
{
   // Get the user name of the person to get
   var userName = url.extension;
}

Post Body
function main(){
 
//invalid input
if(!json.has("users")){
    status.setCode(status.STATUS_BAD_REQUEST, "The request body format is error.");
    return;
}

var usersIndex ;
var users = json.get("users");//json array
for (usersIndex = 0; usersIndex < users.length(); usersIndex++){
 //Get user val 
 var currentUser = users.get(usersIndex);
    

}

其他補充

url

A host object providing access to the URL (or parts of the URL) that triggered the web script.
context
Alfresco context path, for example /alfresco
serviceContext
Alfresco service context path, for example /alfresco/service
service
Web script path, for example /alfresco/service/blog/search
full
Web script URL, for example /alfresco/service/blog/search?q=tutorial
templateArgs
a map of substituted token values (within the URI path) indexed by token name
args
Web script URL arguments, for example q=tutorial
match
The part of the web script URL that matched the web script URL template
extension
The part of the web script URL that extends beyond the match path (if there is no extension, an empty string is returned)

For example, imagine a web script URL template of
/user/{userid}
and a web script request URL of
/alfresco/service/user/fred?profile=full&format=html
The url root object will respond as follows:
  • url.context => /alfresco
  • url.serviceContext => /alfresco/service
  • url.service => /alfresco/service/user/fred
  • url.full => /alfresco/service/user/fred?profile=full&format=html
  • url.args => profile=full&format=html
  • url.templateArgs['userid'] => fred
  • url.match => /user/
  • url.extension => fred
Reference:
http://wiki.alfresco.com/wiki/Web_Scripts_Examples#URL_Argument_Handling

星期日, 2月 24, 2013

[Alfresco] 在java backed取得post request body

先前已經用過javascript webscript取的post request body
這次要改用javabacked的方式取得。
範例如下:

public void execute(WebScriptRequest req, WebScriptResponse response) {
     
 
     
     InputStream inputBody = req.getContent().getInputStream();
     String requestBody = RequestBODY.get(inputBody,Charset.forName("utf-8"));

//requestBody:{"parentUUID":"23d97062-5310-4b80-864a-a2232238fd11","uuids":[]}

     System.out.println("requestBody:" + requestBody);

}

星期五, 2月 22, 2013

[Alfresco] 下載Zip

原本的alfresco不支援下載多個檔案與資料夾,可以透過自已實作java backed的方式實現。
以下是找到的範例,不過用的alfresco似乎跟我的不一樣:)
http://code.google.com/p/alfresco-application-samples/

星期三, 2月 06, 2013

[Alfresco] 檢查當前節點下的路徑是否存在


今天想要提升一下目前上傳元件的功能,需要支援拖拉資料夾的上傳。
昨天已經成功上傳所有目錄檔案,只差建資料夾的整合。

需要一個api來自動建立不存在的資料夾!!,之前已經有實作直接建資料夾的webscript。
目前需要一個如何判斷一個資料夾是否存在的方法。
以下是簡單的範例

星期三, 1月 30, 2013

[Alfresco] Tomcat/temp 的上傳暫存檔無法清除

alfresco:3.4.5 深埋很久的bug,用javascript webscript/java backed都會產生暫存檔無法清除的問題 有找到一些討論的訊息 https://issues.alfresco.com/jira/browse/ALF-2363

 =====
 Alfresco QA Team added a comment - 19-May-10 03:23 PM Validated against 3.3.0 beta 39. 
Temp files are removed according to tempFileCleanerTrigger settings in scheduled-jobs-context.xml.

 =====

 alfresco會透過tempFileCleanerTrigger 來清除檔案,相關設定在scheduled-jobs-context.xml。 設定檔路徑在以下/usr/local/TOMCAT/webapps/alfresco/WEB-INF/classes/alfresco

星期二, 11月 13, 2012

[Alfresco] User Quota Issue

如何讓alfresco的quota即時更新, alfresco的工程師說可透過Java backend的ContentUsageService.getUserUsage(userName) 或 覆寫userUsageCollapseJob
https://forums.alfresco.com/en/viewtopic.php?f=27&t=43431
You should be able to get the up-to-date user usage via ContentUsageService.getUserUsage(userName) or else you could consider overriding the userUsageCollapseJob to run more often (eg. every minute instead of every 5 minutes).

If you're running Enterprise 3.4.6 and need more help with this issue then please contact Alfresco Support (if you haven't already).

Regards,
Jan

Ref:
Interface ContentUsageService

星期四, 11月 01, 2012

[Alfresco] Upload Avatar Javascript API


//js

/**
 * User Profile Avatar Upload method
 *
 * @method POST
 * @param username {string}
 *        filedata {file}
 */

function main()
{
   try
   {
      var filename = null;
      var content = null;
      var username = null;

      // locate file attributes
      for each (field in formdata.fields)
      {
         if (field.name == "filedata" && field.isFile)
         {
            filename = field.filename;
            content = field.content;
         }
         else if (field.name == "username")
         {
            username = field.value;
         }
      }

      // ensure all mandatory attributes have been located
      if (filename == undefined || content == undefined)
      {
         status.code = 400;
         status.message = "Uploaded file cannot be located in request";
         status.redirect = true;
         return;
      }
      if (username == null || username.length == 0)
      {
         status.code = 500;
         status.message = "Username parameter not supplied.";
         status.redirect = true;
         return;
      }

      var user = people.getPerson(username);
      // ensure we found a valid user and that it is the current user or we are an admin
      if (user == null ||
          (people.isAdmin(person) == false && user.properties.userName != person.properties.userName))
      {
         status.code = 500;
         status.message = "Failed to locate user to modify or permission denied.";
         status.redirect = true;
         return;
      }

      // ensure cm:person has 'cm:preferences' aspect applied - as we want to add the avatar as
      // the child node of the 'cm:preferenceImage' association
      if (!user.hasAspect("cm:preferences"))
      {
         user.addAspect("cm:preferences");
      }

      // remove old image child node if we already have one
      var assocs = user.childAssocs["cm:preferenceImage"];
      if (assocs != null && assocs.length == 1)
      {
         assocs[0].remove();
      }

      // create the new image node
      var image = user.createNode(filename, "cm:content", "cm:preferenceImage");
      image.properties.content.write(content);
      image.properties.content.guessMimetype(filename);
      image.properties.content.encoding = "UTF-8";
      image.save();

      // wire up 'cm:avatar' target association - backward compatible with JSF web-client avatar
      assocs = user.associations["cm:avatar"];
      if (assocs != null && assocs.length == 1)
      {
         user.removeAssociation(assocs[0], "cm:avatar");
      }
      user.createAssociation(image, "cm:avatar");

      // save ref to be returned
      model.image = image;
   }
   catch (e)
   {
      var x = e;
      status.code = 500;
      status.message = "Unexpected error occured during upload of new content.";
      if(x.message && x.message.indexOf("org.alfresco.service.cmr.usage.ContentQuotaException") == 0)
      {
         status.code = 413;
         status.message = x.message;
      }
      status.redirect = true;
      return;
   }
}

main();



//description

  Avatar Upload
  Upload avatar file content and apply to person preferences
 
  user
  required
  /slingshot/profile/uploadavatar



//template
{
<#if person.childAssocs["cm:preferenceImage"]??>
"avatar": "${person.childAssocs["cm:preferenceImage"][0].downloadUrl}"
</#if>
<#if person.associations["cm:avatar"]??>
<#if person.associations["cm:avatar"][0].childAssocs["rn:rendition"]??>
,"avatarthumb": "${person.associations["cm:avatar"][0].childAssocs["rn:rendition"][0].downloadUrl}"
</#if>
</#if>
}

星期一, 7月 02, 2012

[Alfresco] 實作alfreso javabacked 上傳心得 How to upload file using java backed web script

本文記錄使用Java API實作上傳的測試心得
上網找到的取得HttpServletRequest 都不適用於alfresco 3.4.5版本

// NOTE: This web script must be executed in a HTTP Servlet environment
//        if (!(req instanceof WebScriptServletRequest)) {
//                throw new WebScriptException(
//                                "Content retrieval must be executed in HTTP Servlet environment");
//        }
     
// HttpServletRequest httpReq = ((WebScriptServletRequest)req).getHttpServletRequest();

發生錯誤如下: ClassCastException


protected Map<string, object> executeImpl(
   WebScriptRequest req,
   Status status, 
   Cache cache) {
WrappingWebScriptRequest wrappingWebScriptRequest = (WrappingWebScriptRequest) req;
  WebScriptRequest webScriptRequest = wrappingWebScriptRequest.getNext(); 
  WebScriptServletRequest servletRequest = (WebScriptServletRequest) webScriptRequest;
  FormField uploadFile = servletRequest.getFileField("file");
  //file field     
  uploadFileName = uploadFile.getFilename();
     uploadMIMEType = uploadFile.getMimetype();
     uploadContent = uploadFile.getInputStream();
     System.out.println("[form data] filename:" + uploadFileName);
     System.out.println("[form data] mimetype:" + uploadMIMEType);
//do something
}

用以下這段程式就能正常取得上傳檔案了,先前的中文問題出在client指定錯誤編碼了,繞了一大圈竟然是手誤呀!!
  

//how to get WebScriptServletRequest
  WrappingWebScriptRequest wrappingWebScriptRequest = (WrappingWebScriptRequest) req;
  WebScriptRequest webScriptRequest = wrappingWebScriptRequest.getNext(); 
  WebScriptServletRequest servletRequest = (WebScriptServletRequest) webScriptRequest;
  
  //get data form form
  FormData formData = (FormData)servletRequest.parseContent();
  FormData.FormField[] formFields = formData.getFields();
  int fieldsLen = formFields.length;
  for(int i=0;i

如果要做更複雜的行為不在這篇的討論範例 :)

星期一, 6月 25, 2012

[Alfresco] Java Foundation API

記錄一下Alfresco low level的java API學習資源 :)


Content repository services

Content repository services are the fundamental services for working with content in Alfresco. Content repository services are written in Java.
Content repository services are built on the storage and query engines. As with the engines, the same infrastructure is shared. The concept of users and groups is introduced into these services, such as recording the author of content, who has content locked or access to content. Implementation of the standards-defined services is packaged into the Alfresco content repository.
Out-of-the-box content repository services provide capabilities to:
  • Organize and manage content
  • Control versions
  • Record changes and updates
  • Enforce security
  • Model content types
  • Search for information in the repository



Search Service
http://wiki.alfresco.com/wiki/Search#Search_Parameters
https://wiki.alfresco.com/wiki/Search_Documentation#Lucene_Language
How to exceed Lucene Limit Search?

星期二, 6月 19, 2012

[Alfresco] How to create Java backed web script in alfresco (3)

這個範例在Google都找的到,沒做多大的修改。
重點是記錄Spring Bean XML的差異性。
Spring Bean XML 
重點在於property標籤設定,如果你參考了foundation的api請記得把他加進來!!,
所以這個範例要使用了Repository,請設定rel=repositoryHelper。
 <bean
         id="webscript.org.example.simplejavadir.get"
         class="org.example.SimpleJavaDir"
         parent="webscript">
                <property name="repository" ref="repositoryHelper"/>
        </bean>

Java backed controller
透過xml的設定, 就可以透過 public void setRepository(Repository repository) {}直接呼叫alfresco的核心api了。
package org.example;
import java.util.HashMap;
import java.util.Map;

import org.alfresco.repo.model.Repository;
import org.alfresco.service.cmr.repository.NodeRef;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;

public class SimpleJavaDir extends DeclarativeWebScript {
 
 private Repository repository;
 
    private static Log s_logger = LogFactory.getLog(SimpleJavaDir.class);


 public void setRepository(Repository repository) {
  this.repository = repository;
 }

 @Override
 protected Map<string, object>  executeImpl(WebScriptRequest req,
   Status status, Cache cache) {

  s_logger.debug("SimpleJavaDir entry");
  
  // extract folder listing arguments from URI
  String verboseArg = req.getParameter("verbose");
  Boolean verbose = Boolean.parseBoolean(verboseArg);
  Map<string, string>  templateArgs = req.getServiceMatch().getTemplateVars();
  String folderPath = templateArgs.get("folderpath");
  String nodePath = "workspace/SpacesStore/" + folderPath;

//  @param1 one of "node", "path", or "avmpath"
  NodeRef folder = repository.findNodeRef("path", nodePath.split("/"));
  // validate that folder has been found
  if (folder == null) {  
   throw new WebScriptException(Status.STATUS_NOT_FOUND, "Folder "
     + folderPath + " not found");
   //you will see the followning messages in your server
//    ERROR [extensions.webscripts.AbstractRuntime] Exception from executeScript - redirecting to status template error: 05190001 Folder Company Homes not found

  }
  
  // construct model for response template to render
   Map<string, object> model = new HashMap<string, object>();
  model.put("verbose", verbose);
  model.put("folder", folder);
  model.put("nodePath", nodePath);
  return model;
 }
}


星期一, 5月 28, 2012

[Alfresco] Alfresco Namespace

Note: This list will expand / change between now and the next release.
NamespaceCommon PrefixDescription
http://www.alfresco.orgalfGeneral Alfresco Namespace
http://www.alfresco.org/model/dictionary/1.0dData Dictionary model
http://www.alfresco.org/model/system/1.0sysRepository system model
http://www.alfresco.org/model/content/1.0cmContent Domain model
http://www.alfresco.org/model/application/1.0appApplication model
http://www.alfresco.org/model/bpm/1.0bpmBusiness Process Model
http://www.alfresco.org/model/site/1.0stSite Model
http://www.alfresco.org/model/forum/1.0fmForum Model
http://www.alfresco.org/model/user/1.0usrUser model (in repository.jar)
http://www.alfresco.org/view/repository/1.0viewAlfresco Import / Export View
http://www.alfresco.org/model/action/1.0actAction service model
http://www.alfresco.org/model/rule/1.0ruleRule service model
http://www.alfresco.org/ws/service/authentication/1.0authAuthentication Web Service
http://www.alfresco.org/ws/service/repository/1.0repRepository Web Service
http://www.alfresco.org/ws/service/content/1.0contentContent Web Service
http://www.alfresco.org/ws/service/authoring/1.0authorAuthoring Web Service
http://www.alfresco.org/ws/service/classification/1.0clsClassification Web Service
http://www.alfresco.org/ws/cml/1.0cmlContent Manipulation Language
http://www.alfresco.org/ws/model/content/1.0cmWeb Service Content Domain Model
http://www.alfresco.org/ws/headers/1.0hdrSOAP Headers
http://www.alfresco.org/model/workflow/1.0wfWorkflow Model(link is to Alfresco simple workflow model, not generally extended)

星期四, 3月 29, 2012

[Alfresco] How to create Java backed web script in alfresco (2)

痛過的經驗記錄一下。
看過上一篇的Java backed 架構圖之後,
得知我們需要完成四個Components,
分別是
1.XML descriptor document (Describing the web script)
2.Freemarker (Writing the response template-FTL)
3.Java class (Writing the web script controller)
4.Spring bean XML(Register the Java class in the Alfresco)

星期四, 3月 08, 2012

[Alfresco] 模擬上傳大頭照發生錯誤


11:24:45,307  ERROR [node.integrity.IntegrityChecker] Found 1 integrity violations:
Invalid property value:
   Node: workspace://SpacesStore/f07b92c9-e188-4991-b55d-eef404d60eda
   Type: {http://www.alfresco.org/model/content/1.0}content
   Property: {http://www.alfresco.org/model/content/1.0}name
   Constraint: 02090038 Value '?????????????????????.png' is not valid as a file name.
This property must be a valid file name.

很明顯又是中文亂碼的問題,查了一下就是在Multipart/data-form的時候,
使用getbytes的方法時,未指定utf-8編碼,導致抓的預設編碼跟自已的VM環境不一致而產生的錯誤。

星期一, 2月 20, 2012

[Alfresco] How to create Java backed web script in alfresco (1)


基於以下理由所以選擇java-backed web script的作法:
1.accessing alfresco application services not available via JavaScript API
2.when the performance is absolutely critical
3.to get tighter control of the generated response.
4.when we need to access the Alfresco API
5.if we prefer stronger programming language like JAVA

透過上面的架構圖,我們可以知道需要準備四個元件
1.XML descriptor document (Describing the webscript controller)
2.Freemarker (Writing the response template-FTL)
3.Java class (Writing the webscript)
4.Spring bean XML(Register the Java class in the Alfresco)

接著準備來寫一個Java Backed Web Script吧~
[Alfresco] How to create Java backed web script in alfresco (2)

Reference:
Alfresco Help Java backed web script
Alfresco WiKi: Java backed web script samples
Alfresco Blog: Java-Backed Web Scripts
Web script article

星期一, 2月 06, 2012

[Alfresco] Boolean type is in FTL

在ftl檔案遇到boolean欄位一開始所遇到的錯誤

{
"shareDpxStatus": <#if person.properties.shareDpxStatus??>${person.properties.shareDpxStatus}<#else>null
}


原來ftl檔不支援直接將boolean型態印出來,要先轉換成字串型態
解法如下:
{
"shareDpxStatus": <#if person.properties.shareDpxStatus??>${person.properties.shareDpxStatus?string("true","false")}<#else>null
}

星期一, 1月 30, 2012

[Alfresco] Pagination of Lucene

使用javascript API的search.query(searchParameters)方法時,
當skipCount超過一千筆時,會無法取得回傳的結果,
導致客製化分頁會失敗。

找到以下這篇跟我遇到一樣的問題:
Improve the skipCount function not to check the permissions.

記錄一下:
This is an enhancement request for paging offset in FTS query called "skipcount". Alfresco don't have to check permission of skipped items when we specify the skipCount. 

(*1 system.max.permissionChecks 1000 as the default) 

I know the paging search itself won't be affected by the permission check as far as I tested it with an out of box webscripts named "children.get. js". So, in this case it works very fine, because this webscript uses "group.getChildGroups(maxItems, skipCount)" with ModelUtil.paging internally, so with this webscripts I can correctly get the result more than the specified number to the permission check. I attached the webscript, please find the sample-webscripts.zip for your reference. 


But, the problem is that if we use the paging offset in FTS query called "skipcount" combined with the Lucene search query in the WebScripts as follows, then it will be affected by the permission check. I attached the webscirpts named paging-result.zip for your reference. 

    var skipCount = 0 + args["skip"]; 
    var searchParams = {}; 
    searchParams.query = "cm\:name:document*"; 
    searchParams.language = "fts-alfresco"; 
    var paging = {}; 
    paging.maxItems = 100; 
    paging.skipCount = skipCount; 
    paging.totalItems = 100, 
    searchParams.page = paging; 
    var results = search.query(searchParams); 
    model["length"] = results.length; 
    model["results"] = results; 

In this case, when we specify the skipcount below the number of system.max.permissionCheck for example 1000 as the default, and set a proper paging value, then it will return the correct result, but the problem is when we specify skipcount over 1,000, then webscripts returns no results (zero items). 
So, the work around is to set over 1,000 to the "system.acl.maxPermissionChecks" , then we can get the results correctly. But increasing this parameter will give more stress to Alfresco server, so that would be nice if we could improve the function of skipCount since Alfresco don't have to check the permission of skipped items when we specify the skipCount. 


請在repository.properties修正以下二個參數
#
# Properties to limit resources spent on individual searches
#
# The maximum time spent pruning results
system.acl.maxPermissionCheckTimeMillis=100000
# The maximum number of results to perform permission checks against
system.acl.maxPermissionChecks=10000

不過當存取超過10000的時候發生以下例外錯誤!!(待續)
目前限制只能取到一層的一萬筆,當該層超過一萬筆後就拿不到資料!!
Transactional update cache 'org.alfresco.cache.node.aspectsTransactionalCache' is full (10000)

其他你感興趣的文章

Related Posts with Thumbnails