cancel
Showing results for 
Search instead for 
Did you mean: 

Create node with custom content model

driekhof
Champ in-the-making
Champ in-the-making
I've dynamically added a custom content model.  It looks like this:


<model name="agile:task" xmlns="http://www.alfresco.org/model/dictionary/1.0">
   <description>Agile Task Model</description>
   <author></author>
   <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"/>
    </imports>

   <namespaces>
      <!– Define a Namespace for my new definitions –>
      <namespace uri="agile.model" prefix="agile"/>
   </namespaces>
  
   <!– Type and Aspect definitions go here –>
   <types>
      <type name="agile:task">
         <title>Task</title>
         <parent>cm:content</parent>
         <properties>
            <property name="agile:task">
               <type>d:text</type>
            </property>
            <property name="agile:responsibleParty">
               <type>d:text</type>
            </property>
            <property name="agile:toDo">
               <type>d:text</type>
            </property>
            <property name="agile:inProcess">
               <type>d:text</type>
            </property>
            <property name="agile:toVerify">
               <type>d:text</type>
            </property>
            <property name="agile:done">
               <type>d:text</type>
            </property>
         </properties>
      </type>
    </types>  

    <!– TODO:  Aspects and Associations –>
</model>


Now I'd like to create a few nodes in the repository using this content model in my Java-backed WebScript.  I've looked over some example code, and can create nodes from an SDK example like this:


        // code for authenticate and locate the company home node not shown

        // create new content node within company home
        // assign name
        String name = "Foundation API sample (" + System.currentTimeMillis() + ")";
        Map<QName, Serializable> contentProps = new HashMap<QName, Serializable>();
        contentProps.put(ContentModel.PROP_NAME, name);

        // create content node
        NodeService nodeService = registry.getNodeService();
        ChildAssociationRef association = nodeService.createNode(companyHome,
                        ContentModel.ASSOC_CONTAINS,
                        QName.createQName(NamespaceService.CONTENT_MODEL_PREFIX, name),
                ContentModel.TYPE_CONTENT,
                contentProps);
        NodeRef content = association.getChildRef();

        // add titled aspect (for Web Client display)
        Map<QName, Serializable> titledProps = new HashMap<QName, Serializable>();
        titledProps.put(ContentModel.PROP_TITLE, name);
        titledProps.put(ContentModel.PROP_DESCRIPTION, name);
        nodeService.addAspect(content, ContentModel.ASPECT_TITLED, titledProps);

SNIP


I assume I'm pretty close, but I need a little help.  How do I change the above Java Code so it creates nodes of my custom content type?  What names/values do I need to use out of my custom content type XML?  Are there any Java code examples of creating custom content model nodes?
4 REPLIES 4

afaust
Legendary Innovator
Legendary Innovator
Hello,

you need to change ContentModel.TYPE_CONTENT to the QName that represents your custom type. How you can create a QName is shown in the very same statement for the childAssocQName parameter. You only need the namespace URI of your model and the local name of your type for this.

Regards
Axel

driekhof
Champ in-the-making
Champ in-the-making
Thanks for the tips.  I'm still failing though.  Not sure I have the right values for the parameters you mention.  Here's what I've tried (among other guesses).

Here's the Namespace from my model.xml:


   <namespaces>
      <!– Define a Namespace for my new definitions –>
      <namespace uri="agile.model" prefix="ag"/>
   </namespaces>


Here's the Java code I'm trying:


        // Local name - use whatever I want for it:
        String name = "Agile Task sample (" + System.currentTimeMillis() + ")";
       
        // Setting some dummy values for properties
        Map<QName, Serializable> contentProps = new HashMap<QName, Serializable>();
        contentProps.put( QName.createQName( "ag:task" ), "task1" );
        contentProps.put( QName.createQName( "ag:responsibleParty" ), "rp1" );
        contentProps.put( QName.createQName( "ag:toDo" ), "td1" );
        contentProps.put( QName.createQName( "ag:inProcess" ), "ip1" );
        contentProps.put( QName.createQName( "ag:toVerify" ), "tv1" );
        contentProps.put( QName.createQName( "ag:done" ), "d1" );
       
        // create content node
        NodeService nodeService = registry.getNodeService();
        ChildAssociationRef association =
            nodeService.createNode( companyHome,
                                    ContentModel.ASSOC_CONTAINS,
                                    QName.createQName( NamespaceService.CONTENT_MODEL_PREFIX, name ),
                                    QName.createQName( "agile.model", name ),
                                    contentProps);

Here's the exception I'm getting when the code executes to try and create a node:

java.lang.IllegalArgumentException: Class {agile.model}Agile Task sample (1344965981608) has not been defined in the data dictionary
   at org.alfresco.repo.policy.ClassPolicyDelegate.get(ClassPolicyDelegate.java:96)
   at org.alfresco.repo.policy.ClassPolicyDelegate.get(ClassPolicyDelegate.java:81)
   at org.alfresco.repo.node.AbstractNodeServiceImpl.invokeBeforeCreateNode(AbstractNodeServiceImpl.java:280)
   at org.alfresco.repo.node.db.DbNodeServiceImpl.createNode(DbNodeServiceImpl.java:345)
   at sun.reflect.GeneratedMethodAccessor795.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
   at org.alfresco.repo.tenant.MultiTNodeServiceInterceptor.invoke(MultiTNodeServiceInterceptor.java:104)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
   at $Proxy8.createNode(Unknown Source)
   at sun.reflect.GeneratedMethodAccessor795.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.alfresco.repo.service.StoreRedirectorProxyFactory$RedirectorInvocationHandler.invoke(StoreRedirectorProxyFactory.java:215)
   at $Proxy9.createNode(Unknown Source)
   at org.alfresco.repo.node.MLPropertyInterceptor.invoke(MLPropertyInterceptor.java:278)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.node.NodeRefPropertyMethodInterceptor.invoke(NodeRefPropertyMethodInterceptor.java:183)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.node.NodeRefPropertyMethodInterceptor.invoke(NodeRefPropertyMethodInterceptor.java:183)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
   at $Proxy8.createNode(Unknown Source)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
   at org.alfresco.repo.audit.DisableAuditableBehaviourInterceptor.invoke(DisableAuditableBehaviourInterceptor.java:113)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:80)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.security.permissions.impl.ExceptionTranslatorMethodInterceptor.invoke(ExceptionTranslatorMethodInterceptor.java:46)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.audit.AuditMethodInterceptor.invoke(AuditMethodInterceptor.java:159)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.transaction.RetryingTransactionInterceptor$1.execute(RetryingTransactionInterceptor.java:69)
   at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:388)
   at org.alfresco.repo.transaction.RetryingTransactionInterceptor.invoke(RetryingTransactionInterceptor.java:59)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
   at $Proxy8.createNode(Unknown Source)
   at org.alfresco.module.demoscripts.AgileFormsWebScript.doExample(AgileFormsWebScript.java:153)
   at org.alfresco.module.demoscripts.AgileFormsWebScript.execute(AgileFormsWebScript.java:67)

I'm fairly sure I have my custom content model deployed correctly.  I was trying to dynamically add it, but I was getting an error shown in this google thread:

http://code.google.com/p/alfresco-form-model-management/issues/detail?can=2&start=0&num=100&q=&colsp...

So I bootstrapped it instead and don't see any errors on server startup.  Not sure how to verify that it is loaded though.

afaust
Legendary Innovator
Legendary Innovator
Hello,

your problem lies here:
String name = "Agile Task sample (" + System.currentTimeMillis() + ")";
and here:
ChildAssociationRef association =
            nodeService.createNode( companyHome,
                                    ContentModel.ASSOC_CONTAINS,
                                    QName.createQName( NamespaceService.CONTENT_MODEL_PREFIX, name ),
                                    QName.createQName( "agile.model", name ),
                                    contentProps);

You should not use
QName.createQName( "agile.model", name )
for your type QName, but instead
QName.createQName( "agile.model", "task")
since otherwise you are not referring to your defined type.

Regards
Axel

driekhof
Champ in-the-making
Champ in-the-making
Thanks, I think it worked!  I can't see the content type of the node created anywhere in the Alfresco UI except for the doc_info.ftl template.  It shows the type as {agile.task.model}task and also shows the values of the dummy properties I set:


Current Document Info:
Name: 2baa05c7-b7e0-4e47-a1c2-0566cae0e05c
Ref: workspace://SpacesStore/2baa05c7-b7e0-4e47-a1c2-0566cae0e05c
Type: {agile.task.model}task
DBID: 986
Content URL: /contentspace/d/d/workspace/SpacesStore/2baa05c7-b7e0-4e47-a1c2-0566cae0e05c/2baa05c7-b7e0-4e47-a1c2-0566cae0e05c
Locked: No
Aspects:
{http://www.alfresco.org/model/content/1.0}auditable
{http://www.alfresco.org/model/system/1.0}referenceable
{http://www.alfresco.org/model/content/1.0}titled
{http://www.alfresco.org/model/system/1.0}localized
{http://www.alfresco.org/model/content/1.0}templatable
Assocs:
Properties:
{http://www.alfresco.org/model/content/1.0}creator = admin
{}ag:toDo = td1
{http://www.alfresco.org/model/system/1.0}locale = en_US
{}ag:done = d1
{http://www.alfresco.org/model/system/1.0}store-protocol = workspace
{}ag:responsibleParty = rp1
{http://www.alfresco.org/model/content/1.0}content = org.alfresco.repo.template.BaseContentNode$TemplateContentData@51dc01c8
{http://www.alfresco.org/model/content/1.0}title = Agile Task sample (1344975261357)
{http://www.alfresco.org/model/system/1.0}node-uuid = 2baa05c7-b7e0-4e47-a1c2-0566cae0e05c
{http://www.alfresco.org/model/content/1.0}modifier = admin
{http://www.alfresco.org/model/content/1.0}name = 2baa05c7-b7e0-4e47-a1c2-0566cae0e05c
{http://www.alfresco.org/model/content/1.0}modified = Aug 14, 2012 1:24:07 PM
{}ag:task = task1
{http://www.alfresco.org/model/content/1.0}template = Node Type: {http://www.alfresco.org/model/content/1.0}content Node Ref: workspace://SpacesStore/f167bfd0-b811-456e-b7a7-bc2dfd0fe4da
{}ag:toVerify = tv1
{http://www.alfresco.org/model/content/1.0}created = Aug 14, 2012 1:14:21 PM
{http://www.alfresco.org/model/system/1.0}store-identifier = SpacesStore
{http://www.alfresco.org/model/system/1.0}node-dbid = 986
{http://www.alfresco.org/model/content/1.0}description = Agile Task sample (1344975261357)
{}ag:inProcess = ip1

Now I need to experiment with associating tasks with a parent 'Sprint' or 'Backlog' object.  And figure out how to provide views of these custom nodes in Share, and allow users to update them…

Thanks for the help!