Alfresco 는 CMIS 이다. CMIS 를 대상으로 컨텐츠 모델링을 할 때는 일반 RDB 모델링 하듯이 하면 완전 피본다는 것을 뼈저리게 느끼고 있다.
일단, JOIN 이 지원되지 않는다는 것은 타격이 크다. SOLR 은 4.0 이상 부터 JOIN 을 지원하는데, Alfresco 4.0 에서는 SOLR 1.4 버전을 사용한다. CMIS Query 에서 JOIN 을 제공해주는 예제를 확인하여 테스트를 해보았으나 커스텀 타입의 데이터 모델은 "Advanced join is not supported" 익셉션만 뱉을 뿐이다...
검색을 하다가 찾은 내용인데, 안습...
The bottom-line is that Alfresco isn't relational. You can set up associations and through the API you can ask a give node for its associations, but you cannot run queries across associations like you can when you do joins in a relational database.
Maybe you should add a location property to your content node and update its value with a behavior any time an association is created, updated, or deleted on that node. Then you'd be able to run a query by AND-ing the location with other criteria on the node.
Obviously, if you have many such properties that you need to keep in sync your behavior could start to affect performance negatively, but if you have only a handful you should be okay.
inform a client of an error situation (for example, item not found)
inform a client of an occurrence of an event (for example, item created)
instruct a client to perform a follow-up request (for example, authorization required)
inform a client of success
Response status codes are set in the controller script via thestatusroot object.
We can add a status to our Hello World example indicating that we can only greet one person at a time i.e. the 'to' argument is specified only once. We can use status code 400 (Bad Request) to represent this. The controller script is extended as follows:
if (argsM.to != null && argsM.to.length > 1)
{
status.code = 400;
status.message = "Can only greet one person at a time.";
status.redirect = true;
}
else
{
model.toWho = (args.to != null) ? args.to : person.properties.userName;
}
Redirect allows the rendering of a custom response template for the specified status code. If redirect is not set (that is, false), the response header status code is set but the relevant standard web script response template is used, as would normally apply.
If redirect is true, then an appropriate status response template is searched for. The search is performed in the following order:
Web Script specific template named<scriptid>.<method>.<format>.<code>.ftl
located in the same folder as the web script description document and used for the specified status code only, for example /org/alfresco/sample/helloworld.get.html.400.ftl
Web Script specific template named<scriptid>.<method>.<format>.status.ftl
located in the same folder as the web script description document used for any status code, for example
this template is first located in the package of the web script, but if not found, is searched for in the parent package hierarchy, up to the root package, for example /org/alfresco/sample/html.400.ftl
Package level template named<format>.status.ftl
this template is first located in the package of the web script, but if not found, is searched for in the parent package hierarchy, up to the root package, for example /org/alfresco/sample/html.status.ftl
Default template named<code>.ftl
located in the root package and always renders html, for example /400.ftl
Default template namedstatus.ftl
located in the root package (provided out-of-the-box) and always renders html, for example /status.ftl
Status Response templates have access to the same root objects as standard Web Script response templates. The exception is that the default templates/<code>.ftland/status.ftlonly have access to the root objects 'url', 'status', 'server' and 'date'.
To provide a custom Bad Request status response for our Hello World example we create the following file in the same folder as the web script description document
helloworld.get.html.400.ftl
whose content is
<html>
<body>
${status.message}
</body>
</html>
We can also provide a meaningful response for machine-readable XML requests:
Remember, these templates are optional, as the search for an appropriate status template will always eventually find the default template/status.ftl.
이번 포스팅에서 사용하는 방식은 "Package level template named <format>.status.ftl" 으로 사용하는 Web Scripts 와 같은 패키지(디렉토리)에 위치시키고 js 파일에서 status 를 제어하여 redirect 를 시킬 것이다.
위에서 redirectCondition 이 true 이면, status.code 에 899 값을 설정하고, status.location 에는 redirect 할 url 을, status.redirect 는 true 로 설정을 하고 실행하는 함수 자체를 return 시켜서 아래 코드가 실행되지 않도록 한다.
각 프로퍼티의 인덱싱 행위는 컨텐츠 모델에서 설정될 수 있다. 기본적으로 원자적으로 인덱싱 된다. 프로퍼티 값은 인덱스 안에 저장되지 않고, 프로퍼티는 인덱싱 될 때, 토큰화 된다.
The following example shows how indexing can be controlled.
Enabled="false"
false 이면, 인덱스에 이 프로퍼티를 위한 엔트리는 없다.
Atomic="true"
true 이면, 프로퍼티는 트랜잭션 내에서 인덱싱되며, false 이면 프로퍼티는 백그라운드에서 인덱싱 된다.
(Indexing of content that requires transformation before being indexed (e.g. PDFs) will only obey Atomic=true if the transformation takes less time than the value specified for lucene.maxAtomicTransformationTime. See #General.)
Stored="true"
true 이면, 프로퍼티 값은 인덱스 내에 저장되고, 루씬 로우 레벨 쿼리 API를 통해 얻을 수 있다.
(This can be useful while debugging systems to see exactly what is being indexed, but do not set this to true on production systems.)
"<configRootShare>/classes/alfresco/share-config.xml" 파일을 오픈한다. 예를 들어 톰캣이라면 "<TOMCAT_HOME>/webapps/share/WEB-INF/classes/alfresco/share-config.xml" 파일을 연다.
위와 같이 "Global config" 영역에 헤더가 정의되어 있다.
2. share-config-custom.xml.sample 파일을 오픈한다.
"<web-extension>/share-config-custom.xml.sample" 파일을 오픈한다. 예를 들어 톰캣이라면 "<TOMCAT_HOME>/shared/classes/alfresco/web-extension/share-config-custom.xml.sample" 파일을 연다.
1번의 <header> 부분을 share-config-custom.xml 파일에 복사합니다.
3. naver 링크 추가
alfresco-config > config > header > app-items 에 새로운 item 엘리먼트를 추가한다.
위의 8번 줄과 같이 naver 링크를 추가한다. (item 엘리먼트의 자세한 설명은 다른 포스팅을 통해 정리할 예정이다)
4. share-config-custom.xml 파일로 저장한다.
"<web-extension>/share-config-custom.xml" 파일로 저장한다. 예를 들어 톰캣이라면 "<TOMCAT_HOME>/shared/classes/alfresco/web-extension/share-config-custom.xml" 파일로 저장한다.
Label & Description & Icon 설정
위의 설정을 추가한 후, 알프레스코를 재시작 하면 "header.naver.id" 라는 레이블의 링크가 생긴다. 이러한 링크를 원하는 레이블로 변경하려면 다음과 같은 작업이 필요하다.
1. share-config-custom.xml 파일로 저장한다.
"<configRootShare>/classes/alfresco/messages/slingshot.properties" 파일을 오픈한다. 예를 들어 톰캣이라면 "<TOMCAT_HOME>/webapps/share/WEB-INF/classes/alfresco/messages/slingshot.properties" 파일을 연다.
header.naver.label=Naver
header.naver.description=Naver...
위의 label 과 description 을 추가한 후, 알프레스코를 재시작하면 정상적으로 label 과 description 이 표시된다. 하지만 아이콘이 없어 다른 링크와 어울리지 않는다.
2. icon 이미지를 추가한다.
이번 포스팅에서 사용하는 네이버 링크의 이미지는 네이버에서 16 x 16 사이즈의 png 이미지를 다운받았다. 이 파일을 "naver.png" 로 저장한 후 (<item id="{id}" /> 에서 사용한 {id}.png 로 저장한다) "<TOMCAT_HOME>/webapps/share/components/images/header" 디렉토리에 복사한다.