cancel
Showing results for 
Search instead for 
Did you mean: 

Contraint ListOfValuesConstraint: inject searchService

denis_miorandi
Champ in-the-making
Champ in-the-making
I'm using a customized ListOfValuesContraint. It work but i need to inject searchService to do something more.
Constraint definition allow only parameters. How can i pass property ref searchService to injectit?

    <constraints>
        <constraint name="docks:CustomerListConstraint" type="com.lion.ecm.model.contraints.ListOfCustomersQueryConstraint" >      
            <!– NEED TO INJECT searchService here to pass to contraint class–>
            <parameter name="caseSensitive">
                <value>true</value>
            </parameter>
        </constraint>
    </constraints>
7 REPLIES 7

jpotts
World-Class Innovator
World-Class Innovator
You don't inject it as part of the model, you inject it in a Spring bean config, like this:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>

<beans>
   <bean id="ListOfCustomersQueryConstraint" class="com.lion.ecm.model.contraints.ListOfCustomersQueryConstraint">
       <property name="searchService">
          <ref bean="SearchService" />       
        </property>
    </bean>
</beans>

So leave the model constraint definition as you have it, but add the above bean config to your model-context.xml file.

Jeff

denis_miorandi
Champ in-the-making
Champ in-the-making
Ok I understand. I've tried but it doesn't work for me. SearchService inside contraint init metod is always null.
Can you take a look at my code and tell me if there are something wrong?
Tks

This is my context file


<beans>
    <!– Registration of new models –>   
    <bean id="docks.docksBillingModel" parent="dictionaryModelBootstrap" depends-on="dictionaryBootstrap">
        <property name="models">
            <list>
                <value>com/lion/ecm/aspects/docksBillingModel.xml</value>
            </list>
        </property>
    </bean>
   <bean id="ListOfCustomersQueryConstraint"
      class="com.lion.ecm.model.contraints.ListOfCustomersQueryConstraint">
      <property name="searchService">
         <ref bean="SearchService" />
      </property>
    </bean>
</beans>

this is my model


<?xml version="1.0" encoding="UTF-8"?>
<model xmlns="http://www.alfresco.org/model/dictionary/1.0" name="docks:docksBillingModel">
    <description>Docks Model</description>
    <author>Denis Miorandi</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="http://www.lion.org/model/content/1.0" prefix="docks"/>
    </namespaces>
    <data-types/>
    <constraints>
        <!– constraint name="docks:CustomerListConstraint" type="LIST"–>
[b]        <constraint name="docks:CustomerListConstraint" type="com.lion.ecm.model.contraints.ListOfCustomersQueryConstraint" >      
            <!– parameter name="allowedValues">
                <list>
                    <value>ABC</value>
                    <value>DEF</value>
                </list>
            </parameter–>
            <parameter name="caseSensitive">
                <value>true</value>
            </parameter>
        </constraint>[/b]
    </constraints>
    <types>
        <type name="docks:document">
            <title>Docks Document</title>
            <parent>cm:content</parent>
            <properties>
                <property name="docks:numbers">
                    <type>d:text</type>
                    <mandatory>false</mandatory>
                    <index enabled="true"/>
                </property>
                <property name="docks:childNumbers">
                    <type>d:text</type>
                    <mandatory>false</mandatory>
                    <index enabled="true"/>
                </property>
                <property name="docks:documentType">
                    <type>d:text</type>
                    <mandatory>false</mandatory>
                    <index enabled="true"/>
                </property>
                <property name="docks:documentParsed">
                    <type>d:boolean</type>
                    <mandatory>false</mandatory>
                    <index enabled="true"/>
                </property>
                <property name="docks:documentAggregated">
                    <type>d:boolean</type>
                    <mandatory>false</mandatory>
                    <index enabled="true"/>
                </property>
                <property name="docks:documentEmail">
                    <type>d:text</type>
                    <mandatory>false</mandatory>
                    <index enabled="true"/>
                </property>
                <property name="docks:documentSent">
                    <type>d:boolean</type>
                    <mandatory>false</mandatory>
                    <index enabled="true"/>
                </property>
                <property name="docks:documentCustomer">
                    <type>d:text</type>
                    <mandatory>false</mandatory>
                    <index enabled="true">
                        <atomic>false</atomic>
                        <stored>false</stored>
                        <tokenised>TRUE</tokenised>
                    </index>
                    <constraints>
                        <constraint name="docks:documentCustomerList" ref="docks:CustomerListConstraint" />
                    </constraints>
                </property>
            </properties>
            <associations>
                <child-association name="docks:childsDocumentLink">
                    <title>Related Documents</title>
                    <source>
                        <mandatory>false</mandatory>
                        <many>false</many>
                    </source>
                    <target>
                        <class>docks:document</class>
                        <mandatory enforced="false">false</mandatory>
                        <many>true</many>
                    </target>
                    <duplicate>false</duplicate>
                    <propagateTimestamps>false</propagateTimestamps>
                </child-association>
            </associations>
            <overrides/>
            <mandatory-aspects/>
        </type>
    </types>
    <aspects>
        <aspect name="docks:documentaspect">
            <title>Document details</title>
            <properties>
                <property name="docks:numberAspect">
                    <type>d:text</type>
                    <mandatory>false</mandatory>
                    <index enabled="true"/>
                </property>
            </properties>
            <associations/>
            <overrides/>
            <mandatory-aspects/>
        </aspect>
    </aspects>
</model>


this is my constraint implementation

package com.lion.ecm.model.contraints;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.alfresco.repo.dictionary.constraint.ListOfValuesConstraint;
import org.alfresco.service.cmr.search.SearchService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

// Retreive list of customers via lucene query
public class ListOfCustomersQueryConstraint extends ListOfValuesConstraint
      implements Serializable {

   private static final long serialVersionUID = 1L;
   private static Log logger = LogFactory
         .getLog(ListOfCustomersQueryConstraint.class);

   private SearchService searchService;
   public void setSearchService(SearchService searchService) {
      this.searchService = searchService;
   }

   @Override
   public void initialize() {
      loadDB();
   }

   @Override
   public List<String> getAllowedValues() {
      super.setAllowedValues(loadDB());
      return super.getAllowedValues();
   }

   @Override
   public void setAllowedValues(List allowedValues) {
   }

   protected List<String> loadDB() {
      ArrayList<String> allowedValues = new ArrayList<String>();
      try {
         // do search here
         //searchService.query(searchParameters);
      } catch (Exception e) {
         logger.error("Error on enumerating values of customers");
      } finally {
      }
      return allowedValues;
   }
}

dantuffery
Champ in-the-making
Champ in-the-making
Hi

Injecting the SearchService via Spring would be the normal way to this usually, but Constriants are a bit different. On start up you're injecting the SearchService into a ListOfCustomersQueryConstraint object using Spring. When the ListOfCustomersQueryConstraint object is created by the model is has no reference to the object that was set up using Spring, it creates an object using the new operator, hence the SearchService being null.

If you're using the FormService it is possible to populate constraints by overriding the PropertyFieldProcessor class which has a makeFieldConstriants method. Inject the searchService into your version of the PropertyFieldProcessor and add your logic to get the values from the SearchService and populate the constraint in the makeFieldConstriants method.

Dan

douglascrp
World-Class Innovator
World-Class Innovator
Hey Dan.
I know it's an old post, but I have just faced this problem, and the solution I found was to define the variable, in my case, AuthorityService, as static.

By doing this, the object is always available.

denis_miorandi
Champ in-the-making
Champ in-the-making
at this time I don't using forms and i don't know how to using PropertyFieldProcessor. Have you got a link to an example?
My requirements is just to put a combo with list of users inside standard form. Is there a simpliest way?

dantuffery
Champ in-the-making
Champ in-the-making
If you’re not using the FormService the PropertyFieldProcessor is no good for you.

I assume the list you want to display is in Share and you’re familiar with Alfresco web scripts and YUI. Create a web script in Alfresco that will return the list of users you want in a JSON format. 


{
    "selectOptions": [
        {
            "name": "bob"
        },
        {
            "name": "jill"
        },
        {
            "name": "mark"
        },
        {
            "name": "sarah"
        }
    ]
}

Create a YUI Javascript class in Share that will call your web script in Alfresco when the form page loads, when the response is returned from your Alfresco web script you’ll need to do something like this in YUI:


//get the list element
var targetListEl = Dom.get('targetListId'), html, selectOptions; //targetListId is the id of your select element

if(typeof targetListEl !== "undefined") {
    //Get the select options JSON from the response
    selectOptions = response.json.selectOptions;
    //Generate the select html
    html = '<select id="targetListId" name="targetListId" tabindex="0">';
    //Iterate over the select options list and create the select options tags
    for(i = 0, ii = selectOptions.length; i < ii; i++) {
        html += '<option value="'+ selectOptions[i].name +'">' + selectOptions[i].name + '</option>';
    }
    //update the select html
    targetListEl.outerHTML = html;
}

Using the FormService and a customised PropertyFieldProcessor is a much nicer/cleaner approach, but if you really can't use the FormService this is one way to populate the drop down.

Dan

alstresh
Champ in-the-making
Champ in-the-making

Lets use static Spring service provider

public class ServiceStaticProvider {

    private static NodeService nodeService;
    private static ContentService contentService;
    private static FileFolderService fileFolderService;
    private static SearchService searchService;

    public static NodeService getNodeService() {
        return nodeService;
    }

    public static ContentService getContentService() {
        return contentService;
    }

    public static FileFolderService getFileFolderService() {
        return fileFolderService;
    }

    public static SearchService getSearchService() {
        return searchService;
    }

    public void setNodeService(NodeService nodeService) {
        ServiceStaticProvider.nodeService = nodeService;
    }

    public void setContentService(ContentService contentService) {
        ServiceStaticProvider.contentService = contentService;
    }

    public void setFileFolderService(FileFolderService fileFolderService) {
        ServiceStaticProvider.fileFolderService = fileFolderService;
    }

    public void setSearchService(SearchService searchService) {
        ServiceStaticProvider.searchService = searchService;
    }

}

<bean id="serviceStaticProvider" class="com.wwwwww.ServiceStaticProvider">
    <property name="fileFolderService">
        <ref bean="fileFolderService" />
    </property>

    <property name="nodeService">
        <ref bean="nodeService" />
    </property>

    <property name="contentService">
        <ref bean="contentService" />
    </property>

    <property name="searchService">
        <ref bean="searchService" />
    </property>
</bean>

In you  extension class of ListOfValuesContraint  just use
ServiceStaticProvider.getSearchService()