I'm thinking how to do this:
I have a java backed webscript and need to upload documents. Some of them will be full indexed (content and metadata) and others only index the metadata.
I have read this way to add a custom aspect on model.xml
<aspect name="my:doNotIndexContentControl">
<title>Do Not Index Control</title>
<parent>cm:indexControl</parent>
<overrides>
<property name="cm:isIndexed">
<default>true</default>
</property>
<property name="cm:isContentIndexed">
<default>false</default>
</property>
</overrides>
<aspect name="my:doIndexContentControl">
<title>Index Control</title>
<parent>cm:indexControl</parent>
<overrides>
<property name="cm:isIndexed">
<default>true</default>
</property>
<property name="cm:isContentIndexed">
<default>true</default>
</property>
</overrides>
And I imagine that if I add on my webscript:
getNodeService().addAspect(nodeRef, "my:doNotIndexContentControl", null);
or
getNodeService().addAspect(nodeRef, "my:doIndexContentControl", null);
it puts my custom aspect defined on model in the nodeRef. Is the best solution for my problem? What do you think? Any recommentation?
Thanks!
You could do this. Other way to achieve is to create rule on top of folder under which you are uploading those contents. That rule can add those aspect on new items based on criterias.
But in that case you will have to clearly define criteria which will distinguish between items to be indexed and not to be indexed.
Related
I need to create a model for cities that contains only the fields id, city name, like a sql table but without creating a file that is not inheriting any Alfresco model (content, folder, etc). I can do that? or it is obligatory to inherit from the Alfresco models
By seeing the definition of sys:base (root object) :
<type name="sys:base">
<title>Base</title>
<mandatory-aspects>
<aspect>sys:referenceable</aspect>
<aspect>sys:localized</aspect>
</mandatory-aspects>
</type>
I would say that it should be possible to create a type without inheriting from something.
But the best shot would be to do the try.
You can inherit from sys:base anyway.
You could use a datalist like this to achieve that.
<description>Cities Data List Content model</description>
<version>1.0</version>
<imports>
<!-- Import Alfresco Dictionary Definitions -->
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d"/>
<!-- Import Alfresco Content Domain Model Definitions -->
<import uri="http://www.alfresco.org/model/content/1.0" prefix="cm"/>
<!-- Import Alfresco Data List Model Definitions -->
<import uri="http://www.alfresco.org/model/datalist/1.0" prefix="dl" />
</imports>
<namespaces>
<namespace uri="<<Your uri>>" prefix="cities"/>
</namespaces>
<types>
<!--
Data List Item Type for the custom cities list
-->
<type name="cities:cityListItem">
<title>Cities List Item</title>
<parent>dl:dataListItem</parent>
<properties>
<property name="cities:cityName">
<type>d:text</type>
<mandatory>true</mandatory>
</property>
<property name="cities:cityID">
<type>d:int</type>
<mandatory>true</mandatory>
</property>
<property name="cities:cityDescription">
<type>d:text</type>
</property>
</properties>
</type>
</types>
You can later add more customization related to this datalist as you can see in here:
https://docs.alfresco.com/5.1/references/dev-extension-points-data-lists.html
I'd suggest using AttributeService.
http://docs.alfresco.com/5.2/references/dev-services-attribute.html
Here it is a short description of the situation:
I am declaring a new bean in a private Jar file to add two new Aspects to match Secondary Type feature from CMIS 1.1 specification.
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
<!-- Registration of new models -->
<bean id="myExtension" parent="dictionaryModelBootstrap" depends-on="dictionaryBootstrap">
<property name="models">
<list>
<value>alfresco/extension/my-extension-model_1.xml</value>
<value>alfresco/extension/my-extension-model_2.xml</value>
</list>
</property>
</bean>
</beans>
Here is the code of my-extension-model_1.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Definition of new Model -->
<!-- The important part here is the name - Note: the use of the my: namespace
which is defined further on in the document -->
<model name="my:model_1" xmlns="http://www.alfresco.org/model/dictionary/1.0">
<!-- Optional meta-data about the model -->
<description>Model 1</description>
<author>mtyc</author>
<version>1.0</version>
<!-- Imports are required to allow references to definitions in other models -->
<imports>
<!-- Import Alfresco Dictionary Definitions -->
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d" />
<!-- Import Alfresco Content Domain Model Definitions -->
<import uri="http://www.alfresco.org/model/content/1.0" prefix="cm" />
</imports>
<!-- Introduction of new namespaces defined by this model -->
<!-- NOTE: The following namespace my.new.model should be changed to reflect
your own namespace -->
<namespaces>
<namespace uri="http://www.mycompany.com/model/content/1.0" prefix="my" />
</namespaces>
<aspects>
<aspect name="my:model_1_DedicatedAspect">
<title>My model 1 aspect</title>
<properties>
<property name="my:supplierId">
<type>d:text</type>
<mandatory>true</mandatory>
</property>
<property name="my:companyId">
<type>d:text</type>
<mandatory>true</mandatory>
</property>
<property name="my:orderId">
<type>d:text</type>
</property>
</properties>
</aspect>
</aspects>
</model>
Here is the code of my-extension-model_2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Definition of new Model -->
<!-- The important part here is the name - Note: the use of the my: namespace
which is defined further on in the document -->
<model name="my:model_2" xmlns="http://www.alfresco.org/model/dictionary/1.0">
<!-- Optional meta-data about the model -->
<description>Model 2</description>
<author>mtyc</author>
<version>1.0</version>
<!-- Imports are required to allow references to definitions in other models -->
<imports>
<!-- Import Alfresco Dictionary Definitions -->
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d" />
<!-- Import Alfresco Content Domain Model Definitions -->
<import uri="http://www.alfresco.org/model/content/1.0" prefix="cm" />
</imports>
<!-- Introduction of new namespaces defined by this model -->
<!-- NOTE: The following namespace my.new.model should be changed to reflect
your own namespace -->
<namespaces>
<namespace uri="http://www.mycompany.com/model/content/1.0" prefix="my" />
</namespaces>
<aspects>
<aspect name="my:model_2_DedicatedAspect">
<title>My model 2 aspect</title>
<properties>
<property name="my:supplierId">
<type>d:text</type>
<mandatory>true</mandatory>
</property>
<property name="my:companyId">
<type>d:text</type>
<mandatory>true</mandatory>
</property>
</properties>
</aspect>
</aspects>
</model>
I then build it as a jar and deploy it under Alfresco, which starts successfully and load my models.
In the application I am developing, which is communicating with my alfresco instance, I create documents with aspect my:model_1_DedicatedAspect and documents with aspect my:model_2_DedicatedAspect.
I want to search documents by my:companyId belonging to aspect my:model_1_DedicatedAspect using this CMIS query:
private static ItemIterable<QueryResult> searchClaimsByCompanyId(Session session, String companyId) {
String query = "SELECT d.*, t.* FROM cmis:document as d JOIN my:model_1_DedicatedAspect as t ON d.cmis:objectId = t.cmis:objectId where t.my:companyId = '" + companyId + "'";
ItemIterable<QueryResult> result = session.query(query, false);
return result;
}
The problem is: Result contains documents created with aspect my:model_1_DedicatedAspect BUT ALSO documents created with aspect my:model_2_DedicatedAspect.
After deeper tests, I observed that when I create a document using my:model_1_DedicatedAspect, document is also associated with aspect my:model_2_DedicatedAspect.
Questions: Is there something I am doing wrong ? Is this a bug ? Is there a better way ?
Thanks a lot for your answers,
Max
I'm not sure why it's not giving an error on start-up. But in Alfresco a property must be unique in it's model. So your my:companyId is used twice in different aspects.
The best practice is to create 1 aspect called my:company which has a property my:companyId.
You can just define aspects without property to have a check or search on them.
And btw the CMIS query can be made much easier:
SELECT * FROM my:model_1_DedicatedAspect
So no need for extra joins.
----------UPDATE----------
Since a certain version of Alfresco (I guess it's 4.x) you don't need to add a certain aspect to a node anymore. If you add the aspects property in your case my:companyId, then it will determine which aspect to add automatically. So Alfresco sees 2 aspects with the same property and adds them.
I still haven't heard from you "Why" you're doing it like this? In sense of Content Modeling this doesn't make any sense.
Aspects are just Alfresco's way to add dynamically properties to different content Types.
In your case I'd use inheritance to include the needed property.
I change property by adding tokenised as follows:
<property name="sci:doc">
<type>d:text</type>
<index enabled="true">
<atomic>true</atomic>
<stored>false</stored>
<tokenised>false</tokenised>
</index>
</property>
After fully rebuilding the index and restarting alfresco I searched in node browser using Lucene like this:
PATH:"/app:company_home/app:guest_home/cm:mySpace/*" AND (#sci\:doc:'my doc')
But no result was returned. I also tried (#sci\:doc:'my') OR (#sci\:doc:'doc'). This all failed.
I'm using 3.4.d. I found any property that sets <tokenised> to false has this issue: Search always returns nothing!
I tried alfresco-fts search in node browser, it works for the tokenized property above, but I'm using Alfresco web service, the default QUERY_LANG_LUCENE is lucene. I cannot switch to alfresco-fts.
Any idea how to solve this?
Right now am started working with alfresco. But am not clear about what is type and whats aspect?. please give in detail with example.
Each node on creation has a given type, and just one type, like 'document' or 'folder'. On other hand one node can have many aspects, like 'taggable' or/and 'versionable'.
The node type of a node can change over time, but there is only one type for one node, the aspects are like property attachments, you can add them on creation or in runtime.
Aspects can be also added to many types of nodes, so if you want your model a have special property that will exist in many types, the best way is to create an aspect. Then to maintain your code you only have to maintain the aspect.
Of course you can create your own types and aspects in Alfresco, that is Customizing the content model.
Here is an example of a custom content model:
i:status is a custom aspect.
<?xml version="1.0" encoding="UTF-8"?>
<model xmlns="http://www.alfresco.org/model/dictionary/1.0" name="i:multimediaModel">
<description>Multimedia Model</description>
<author>Pedro Costa</author>
<version>1.0</version>
<imports>
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d"/>
<import uri="http://www.alfresco.org/model/content/1.0" prefix="cm"/>
</imports>
<namespaces>
<namespace uri="pt.i.model" prefix="i"/>
</namespaces>
<constraints>
<constraint name="i:status_constraint" type="LIST">
<parameter name="allowedValues">
<list>
<value>Draft</value>
<value>Pending</value>
<value>Current</value>
<value>Archived</value>
</list>
</parameter>
</constraint>
</constraints>
<types>
<type name="i:multimedia">
<title>Multimedia Metadata Model</title>
<parent>cm:content</parent>
<archive>true</archive>
<properties>
<property name="i:insertDate">
<title>Multimedia insert date</title>
<description>
Multimedia insert date can be diferent of the
insert date in alfresco, this apllies to multimedia
created before database migration to alfresco
</description>
<type>d:datetime</type>
<mandatory>false</mandatory>
</property>
<property name="i:multimediaFormat">
<title>Multimedia Format</title>
<description>Multimedia Format, file type</description>
<type>d:text</type>
<mandatory>false</mandatory>
</property>
<property name="i:contentLength">
<title>Content Length</title>
<description>The file size in bytes</description>
<type>d:long</type>
<mandatory>false</mandatory>
</property>
<property name="i:copyright">
<title>Copyright</title>
<description>Copyright</description>
<type>d:text</type>
<mandatory>false</mandatory>
</property>
</properties>
<mandatory-aspects>
<aspect>cm:taggable</aspect>
<aspect>cm:auditable</aspect>
<aspect>i:status</aspect>
</mandatory-aspects>
</type>
</types>
<aspects>
<aspect name="i:status">
<title>Multimedia Status</title>
<properties>
<property name="i:status">
<title>Status</title>
<type>d:text</type>
<default>Draft</default>
<constraints>
<constraint ref="i:status_constraint" />
</constraints>
</property>
</properties>
</aspect>
</aspects>
</model>
I'll try to create a shorter answer, although the long one is also useful.
As you know, model defines the "types" of data you'll store in the repository.
So, a type is a form of object you'll be storing - together with it's properties like name, title, description in default model or "mytype:amount", "mytype:date" or similar in custom models.
So each document in alfresco is of a certain type (an "user" type, a "folder" type, a "content" type for default model).
And aspect - it's something best described as an additional set of properties.
So, you may have a type: "invoice". It has properties like amount, due date and payee.
But you can also have an aspect, "vendor" - with additional data, like vendor name and vendor account number.
So, you can add aspects to your invoices - add additional properties like vendor name to the invoices. But you can also add this aspect to a "folder" or space in alfresco - for example, you can have a space for a vendor, or a contract or some other document - and to each of those types you can add the aspect "vendor".
I want to build an ant script that does exactly the same compilation actions on a Flash Builder 4 (Gumbo) project as the Project->Export Release Build... menu item does. My ant-fu is reasonably strong, that's not the issue, but rather I'm not sure exactly what that entry is doing.
Some details:
I'll be using the 3.x SDK (say, 3.2 for the sake of specificity) to build this.
I'll be building on a Mac, and I can happily use ant, make, or some weird shell script stuff if that's the way you roll.
Any useful optimizations you can suggest will be welcome.
The project contains a few assets, MXML and actionscript source, and a couple of .swcs that are built into the project (not RSL'd)
Can someone provide an ant build.xml or makefle that they use to build a release .swf file from a similar Flex project?
One quick way to know the compiler options is to add this tag into your compiler options:
-dump-config your/drive/to/store/the/xmlfile.xml
This will output the entire ant compiler options and you can copy off the parts you want to keep.
HellFire Compiler Daemon (http://bytecode-workshop.com/) can generate build.xml directly from the compiler calls made by Flex/Flash Builder. That means your ant script produces SWCs and SWFs based on the exact same set of compiler settings that you set in Flex/Flash Builder.
Also, check out this blog:
http://stopcoding.wordpress.com/2010/01/15/ant-tasks-for-hfcd-now-available-2/
I had some issues with the Adobe Flex Ant tasks a while back, so I ended up using an exec call to the mxmlc compiler with a boatload of options and we've just built upon it from there. There are a few nagging doubts that what I do with the build.xml is not exactly the same that FB3 (what we have) does, but this might be enough to help get you started... you say your ant-fu is reasonably strong, so I'll skip over most of my build file and let you piece together the pieces.
<!--flex stuff-->
<property name="dir.flex.sdk" value="${system.build.flex.sdk}"/>
<property name="dir.flex.home" value="${dir.abc}/flex/sdks/${dir.flex.sdk}"/>
<property name="dir.flex.projects" value="${dir.abcd_plat}/webapp/flexprojects/"/>
<property name="dir.modules" value="${dir.war}/modules/"/>
<property name="FLEX_HOME" value="${dir.flex.home}"/>
<property name="APP_ROOT" value="${dir.war}"/>
<property name="flexc.exe" value="This should be set in the build-${os.family}.xml file"/>
<property name="asdoc.exe" value="This should be set in the build-${os.family}.xml file"/>
<property name="optimizer.exe" value="This should be set in the build-${os.family}.xml file"/>
<property name="flex.mxmlc" value="${dir.flex.home}/bin/${flexc.exe}"/>
<property name="flex.compc" value="${dir.flex.home}/bin/${compc.exe}"/>
<property name="flex.asdoc" value="${dir.flex.home}/bin/${asdoc.exe}"/>
<property name="flex.optimizer" value="${dir.flex.home}/bin/${optimizer.exe}"/>
<property name="flex.options.warnings" value="false"/>
<!--options that are used in common for compiling all .swc and .swf files-->
<property name="flex.meta.1" value="-creator 'MyCorp.' -publisher 'MyCorp.'"/>
<property name="flex.meta.2" value="-title MegaProduct -description http://ourURL.com"/>
<property name="flex.meta.props" value="${flex.meta.1} ${flex.meta.2}"/>
<property name="debug.options" value="-optimize=true -debug=false"/>
<property name="common.flex" value="-as3 -target-player=9.0.124 -warnings=${flex.options.warnings}"/>
<property name="license.flex3" value="(put your own here)"/>
<property name="common.fixed" value="-license=flexbuilder3,${license.flex3} -sp ${dir.war} -library-path+=${dir.webinf}/lib"/>
<property name="flex.common.args" value="${flex.meta.props} ${debug.options} ${common.flex} ${common.fixed}"/>
<!--this is currently unused, but if we make a debug version, this can be set to make a separate output file-->
<property name="swf.suffix" value=""/>
<!--=================================================================================
MACRODEFs
-->
<!--this is used to extract .swf files from 3rd party .swc libraries, in order to do dynamic linking-->
<macrodef name="extract-flex-lib" description="For modularizing flex compilation">
<attribute name="swc-lib" default="NOT SET"/>
<sequential>
<!--use a copy task - it can get the file out of the zip, and rename it at the same time-->
<copy todir="${dir.war}" preservelastmodified="true">
<zipfileset src="${dir.webinf}/lib/#{swc-lib}.swc">
<patternset>
<include name="library.swf"/>
</patternset>
</zipfileset>
<mapper type="glob" from="library.swf" to="#{swc-lib}-debug.swf"/>
</copy>
<!--run the flex optimizer on the extracted .swf - note the as3 metadata that's kept, it's required-->
<exec executable="${flex.optimizer}" failonerror="true">
<arg line="-keep-as3-metadata='Bindable,Managed,ChangeEvent,NonCommittingChangeEvent,Transient'"/>
<arg line="-input #{swc-lib}-debug.swf -output #{swc-lib}.swf"/>
</exec>
<!--delete the unoptimzed swf, don't need it anymore-->
<delete file="#{swc-lib}-debug.swf"/>
</sequential>
</macrodef>
<!--this is used to compile our internal flex modules-->
<macrodef name="flexc-mxml" description="For building the flex modules during flex compilation">
<attribute name="name" default=""/>
<attribute name="mxml.args" default="${flex.common.args} ${module.args}"/>
<attribute name="sourcePath" default=""/>
<attribute name="destPath" default=""/>
<sequential>
<echo message=" Compiling with mxmlc: #{name}"/>
<exec executable="${flex.mxmlc}" failonerror="true">
<arg line="#{mxml.args} #{sourcePath} -output #{destPath}"/>
</exec>
</sequential>
</macrodef>
<!--this is used to compile our subprojects under abcd_plat/webapp/flexprojects-->
<macrodef name="flexc-subproject" description="For compiling the flex subprojects into .swc files">
<attribute name="name" default=""/>
<attribute name="xtra.args" default=""/>
<sequential>
<echo/>
<echo message=" Compiling subproject: #{name}"/>
<xslt in="${dir.flex.projects}/#{name}/.flexLibProperties" out="${dir.flex.projects}/#{name}/src/manifest.xml" style="${dir.war}/build-manifest-style.xsl"/>
<exec executable="${flex.compc}" failonerror="true">
<arg line="-load-config+=${dir.flex.projects}/#{name}/include-files.xml"/>
<arg line="-namespace http://#{name}.ourURL.com ${dir.flex.projects}/#{name}/src/manifest.xml"/>
<arg line="-include-namespaces http://#{name}.ourURL.com #{xtra.args}"/>
<arg line="-library-path+=${dir.webinf}/lib -sp ${dir.flex.projects}/#{name}/src -output ${dir.webinf}/lib/#{name}.swc"/>
</exec>
</sequential>
</macrodef>
<!--=================================================================================
This is where all the compilation is done. The actual work is split among
several different tasks in order to organize them better.
This target uses the html-wrapper task defined in flexTasks.jar - see taskdef above.
-->
<target name="flexcompile" depends="flexc-modularize" description="Builds the Flex sources" unless="flexc.notRequired.main">
<echo message="Compiling MegaProduct Flex application on OS family: ${os.family}"/>
<echo message=" mxmlc is: ${flex.mxmlc}"/>
<echo message=" compc is: ${flex.compc}"/>
<!--compile flex sub-projects first (main application depends on these extra libraries)-->
<antcall target="flexc-projects"/>
<!--compile the main MegaProduct application-->
<antcall target="flexc-main"/>
<!--compile the foobar stuff, which link against the main app. these foorbars are modules
inside a subproject, so they are handled differently from other flex projects and modules-->
<antcall target="flexc-foorbars"/>
<!--generate the html wrapper for the .swf-->
<html-wrapper title="MyCorp MegaProduct" application="app_name" swf="app_name" history="false" template="express-installation"/>
</target>
<target name="flexc-projects">
<!--the name must match the name of the folder exactly, also they are not in parallel as some depend on others-->
<flexc-subproject name="Dockable"/>
<flexc-subproject name="EXRibbon" xtra.args="-source-path+=${dir.flex.projects}/EXRibbon/locale/en_US/"/>
<!--note: MPLib does some extra stuff with the image dir in order to link against images correctly-->
<copy todir="${dir.flex.projects}/MPLib/src/image"><fileset dir="${dir.war}/image"/></copy>
<flexc-subproject name="MPLib"/>
<delete dir="${dir.flex.projects}/MPLib/src/image"/>
</target>
<target name="flexc-main">
<!--the link report is used to create the symbols in the main swf, and modules link against it-->
<property name="link.report" value="${dir.war}/abc_link_report.xml"/>
<!--modular.args is set in flexc-modularize. If not set, this sets it to an empty property-->
<property name="modular.args" value=""/>
<!--set up options specific for the main part and for the modules-->
<property name="main.args" value="-link-report=${link.report} ${modular.args}"/>
<property name="module.args" value="-load-externs=${link.report}"/>
<!--compile abc_flex.mxml here-->
<echo message="Compiling abc_flex application, sub-applications and modules..."/>
<echo/>
<flexc-mxml name="abc_flex" mxml.args="${flex.common.args} ${main.args}"
sourcePath="${dir.war}/abc_flex.mxml" destPath="${dir.war}/abc_flex${swf.suffix}.swf"/>
<!--compile MPMainSubApplication.mxml sub-application here-->
<flexc-mxml name="MPMainSubApplication" mxml.args="${flex.common.args} ${main.args}"
sourcePath="${dir.war}/MPMainSubApplication.mxml" destPath="${dir.war}/MPMainSubApplication.swf"/>
<!--compile internal modules next - just add new modules to the list here -->
<parallel> <!--do in parallel - it goes faster and they don't depend on each other-->
<property name="dir.module.src" value="${dir.war}/module/"/>
<flexc-mxml name="module1" sourcePath="${dir.module.src}/editor/Editor.mxml" destPath="${dir.module.src}/editor/Editor.swf" />
<flexc-mxml name="RunModule" sourcePath="${dir.module.src}/run/RunModule.mxml" destPath="${dir.module.src}/run/RunModule.swf" />
<!--<flexc-mxml name="JobManager" sourcePath="${dir.module.src}/jobmanager/JobManager.mxml" destPath="${dir.module.src}/jobmanager/JobManager.swf" />-->
<flexc-mxml name="Editor2" sourcePath="${dir.module.src}/edit/Editor.mxml" destPath="${dir.module.src}/edit/Editor.swf" />
</parallel>
</target>
NOTES:
I'm not sure if it's a good idea or not, but we just put the .swc files to include with our Java middle tier libs in WEB-INF/lib, so whenever we add a new flex lib to source control we just drop it in there. The compilation is done in the macros, and most of the parameters are defined as properties in the top section. The targets split the work because our app is quite large; you probably don't need those but it's an example of doing modules within sub-projects plus the link-report and follows the way a sub-project is referenced from the main application (I think). Our build machine is linux, so that's why the flexc.exe property (and others) are defined that way - it gets set at runtime. Names have been munged by hand for this answer, so please double-check for typos if you cut-n-paste anything.
Also, the incremental compilation isn't actually used; it seems to be buggy. Ditto for the modularization stuff, so I didn't include that target.
I built all of this myself so I'm rather proud of it, but if there's anything that looks iffy or smells bad, please feel free to let me know. Thanks!