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