cancel
Showing results for 
Search instead for 
Did you mean: 

Dynamic list constraint

ajperez
Champ in-the-making
Champ in-the-making
Hi,

I'm trying to follow the examples provided in this post, to create a dynamic list constraint in Alfresco 3.3.

So, I've created my own class extending ListOfValuesConstraint:


public class MyConstraint extends ListOfValuesConstraint {

   private static ServiceRegistry registry;

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

   @Override
   public List getAllowedValues() {
      loadData();
      return super.getAllowedValues();
   }

   @Override
   public void setAllowedValues(List allowedValues) {
   }

   // Getters and setters for service registry and other things

   protected void loadData() {
      List<String> values = new LinkedList<String>();
      String query = "+TYPE:\"cm:category\" +@cm\\:description:\"" + tipo + "\"";
      StoreRef storeRef = new StoreRef("workspace://SpacesStore");
      ResultSet resultSet = registry.getSearchService().query(storeRef, SearchService.LANGUAGE_LUCENE, query);
      // … values.add(data obtained using searchService and nodeService) …

      if (values.isEmpty()) {
         values.add("-");
      }
      super.setAllowedValues(values);
   }
}
If I only call "loadData()" from initialize(), it works fine: executes the Lucene query, gets the data, and the dropdown displays it correctly. Only that it's not dynamic: data doesn't get refreshed unless I restart the Alfresco server.

"getAllowedValues()" is called each time the UI has to display a property having this constraint. The idea on the referred post is to call "loadData()" from "getAllowedValues()" too, so the values will be actually dynamic. But when I do this, I don't get any data. The Lucene query is the same, but returns 0 results :-?

(BTW, the query I'm doing is: +TYPE:"cm:category" +@cm\:description:"something here")

Any ideas on why is this happening, or how can I solve it?

Thanks
6 REPLIES 6

robain
Champ in-the-making
Champ in-the-making
Hi Did you find any resolution to this. seems like I am having similar issue with this during upgrade.

matjazmuhic
Champ on-the-rise
Champ on-the-rise
Anyone resolved this?

Is there any other way to populate constraint with lucene search results?

paulo_fernandes
Champ in-the-making
Champ in-the-making
This post is rather old.
For documentation purposes, and because its an important question, here is the solution:

    Override initialize() and do nothing
    Don't override setAllowedValues()
    Don't put allowedValues in the super class, return the list directly

Something like this (tested with Alfresco v2.9 and later versions):

SearchBasedListConstraint.java



public abstract class SearchBasedListConstraint extends ListOfValuesConstraint {

   private static ServiceRegistry serviceRegistry = null;
   protected String strStoreRef = "workspace://SpacesStore";
   protected String query = null;
   protected String sortField = null;
   protected Boolean sortDescending = null;

   @Override
        public void initialize() {
      //List<String> allowedValues = getSearchResult();
      //super.setAllowedValues(allowedValues);
        }
   
   @Override
   public List<String> getAllowedValues()
   {
      List<String> allowedValues = getSearchResult();
      //super.setAllowedValues(allowedValues);
      //return super.getAllowedValues();
      return allowedValues;
   }

   protected abstract List<String> getSearchResult();

   
   public ServiceRegistry getServiceRegistry() {
      return serviceRegistry;
   }

   public void setServiceRegistry(ServiceRegistry serviceRegistryParam) {
      serviceRegistry = serviceRegistryParam;
   }

   public String getStrStoreRef() {
      return strStoreRef;
   }

   public void setStrStoreRef(String strStoreRef) {
      this.strStoreRef = strStoreRef;
   }

   public String getQuery() {
      return query;
   }

   public void setQuery(String query) {
      this.query = query;
   }

   public String getSortField() {
      return sortField;
   }

   public void setSortField(String sortField) {
      this.sortField = sortField;
   }

   public Boolean getSortDescending() {
      return sortDescending;
   }

   public void setSortDescending(Boolean sortDescending) {
      this.sortDescending = sortDescending;
   }
   
}



LuceneSearchBaseListConstraint.java


public class LuceneSearchBasedListConstraint extends SearchBasedListConstraint {
   
   protected List<String> getSearchResult() {
      SearchService searchService = getServiceRegistry().getSearchService();
      NodeService nodeService = getServiceRegistry().getNodeService();
      List<String> allowedValues = new ArrayList<String>();

      try {
         StoreRef storeRef = new StoreRef(strStoreRef);
         ResultSet resultSet = null;
         if (sortField != null) {
            SearchParameters sp = new SearchParameters();
            sp.addStore(storeRef);
            sp.setLanguage(SearchService.LANGUAGE_LUCENE);
            sp.setQuery(query);
            sp.addSort(sortField, (sortDescending!=null) ? !sortDescending : true);
            resultSet = searchService.query(sp);
         } else {
            resultSet = searchService.query(storeRef, SearchService.LANGUAGE_LUCENE, query);
         }
      
         for (ResultSetRow row : resultSet) {
            allowedValues.add((String)nodeService.getProperty(row.getNodeRef(), ContentModel.PROP_NAME));
         }
      } catch (Exception e) {
         e.printStackTrace();
      }
   
      return allowedValues;
   }
}

pavaniakella
Champ in-the-making
Champ in-the-making
Hi Paulo,

I tried the following code. But the values are not getting updated dynamically when I add new values to database.



package org.alfresco.ryden;

import java.util.ArrayList;
import java.util.List;
import java.sql.*;
import org.alfresco.repo.dictionary.constraint.ListOfValuesConstraint;
import org.alfresco.web.bean.generator.BaseComponentGenerator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.Serializable;
import javax.faces.model.SelectItem;

public class ListOfValuesQueryConstraint extends ListOfValuesConstraint implements Serializable {

   private static Log logger = LogFactory.getLog(BaseComponentGenerator.class);
  
   private static final long serialVersionUID=1;
  
   private List<String> allowedLabels;
  
   public void setAllowedValues(List allowedValues) {}
   public void setCaseSensitive(boolean caseSensitive) {}

   public void initialize() {
       super.setCaseSensitive(false);
       this.loadDB();
    }
  
   public List<String> getAllowedLabels() {
      return this.allowedLabels;
   }
  
   public void setAllowedLabels(List<String> allowedLabels) {
      this.allowedLabels=allowedLabels;
   }
   
    public List<SelectItem> getSelectItemList() {
      List<SelectItem> result = new ArrayList<SelectItem>(this.getAllowedValues().size());
      for(int i=0;i<this.getAllowedValues().size();i++) {
         result.add(new SelectItem((Object)this.getAllowedValues().get(i),this.allowedLabels.get(i)));
      }
      return result;
   }
   
    protected void loadDB() {
      
       String driverName = "com.mysql.jdbc.Driver";
        String serverName = "localhost:3307";
        String mydatabase = "propertyrecord";
        String username = "propertyrecord";
        String password = "rydenproperty";
      
        List<String> av = new ArrayList<String>();
        List<String> al=new ArrayList<String>();
       
      
        try {
           Connection connection = null;
            Class.forName(driverName);
            String url = "jdbc:mysql://" + serverName +  "/" + mydatabase;
            connection = DriverManager.getConnection(url, username, password);
            Statement stmt = connection.createStatement();
            ResultSet rs = stmt.executeQuery("select propertyRef from propertyrecord");
            while (rs.next()) {
                av.add(rs.getString("propertyRef"));
                al.add(rs.getString("propertyRef"));
            }
        }
        catch (Exception e) {}
      
      super.setAllowedValues(av);
      this.setAllowedLabels(al);
   }
}


<constraint name="dl:PropertyRef" type="org.alfresco.ryden.ListOfValuesQueryConstraint" />

So I changed the code to what you mentioned. The following is the code. With this code I got an error saying allowed values JSON object not found.  Please let me know what am I doing wrong?


package org.alfresco.ryden;

import java.util.ArrayList;


import java.util.List;
import java.sql.*;
import org.alfresco.repo.dictionary.constraint.ListOfValuesConstraint;


public class ListOfValuesQueryConstraint extends ListOfValuesConstraint {

 
   @Override
   public void initialize() {
   }
  
   @Override
   public List<String> getAllowedValues()
   {
      List<String> allowedValues = loadDB();
      //super.setAllowedValues(allowedValues);
      //return super.getAllowedValues();
      return allowedValues;
   }


    protected List<String> loadDB() {
      
       String driverName = "com.mysql.jdbc.Driver";
        String serverName = "localhost:3307";
        String mydatabase = "propertyrecord";
        String username = "propertyrecord";
        String password = "rydenproperty";
      
        List<String> av = new ArrayList<String>();
        List<String> al=new ArrayList<String>();
       
      
        try {
           Connection connection = null;
            Class.forName(driverName);
            String url = "jdbc:mysql://" + serverName +  "/" + mydatabase;
            connection = DriverManager.getConnection(url, username, password);
            Statement stmt = connection.createStatement();
            ResultSet rs = stmt.executeQuery("select propertyRef from propertyrecord");
            while (rs.next()) {
                av.add(rs.getString("propertyRef"));
                al.add(rs.getString("propertyRef"));
            }
            rs=null;
        }
        catch (Exception e) {}
   
      return av;
   }
}
and the constraint declaration is

<constraint name="dl:PropertyRef" type="org.alfresco.ryden.ListOfValuesQueryConstraint" />

Regards,
Pavani

alarocca
Champ in-the-making
Champ in-the-making
On Share 3.4.d, getAllowedValues() is called just once at startup. This is the reason why the list never updates.

Since I successfully used the same solution on an older release of Alfresco Explorer, I guess the problem is on gui instead of the custom constraint.

This post is rather old.
For documentation purposes, and because its an important question, here is the solution:

    Override initialize() and do nothing
    Don't override setAllowedValues()
    Don't put allowedValues in the super class, return the list directly

glaenen
Champ in-the-making
Champ in-the-making
On alfresco 4.0d adding

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

to your constraint class does the trick, ou don't have to change the initialize.

Kind Regards,

Glenn