/**
* Copyright 2010 JBoss Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.drools.guvnor.client.packages;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.drools.factconstraints.client.ConstraintConfiguration;
import org.drools.guvnor.client.common.GenericCallback;
import org.drools.guvnor.client.modeldriven.SetFactTypeFilter;
import org.drools.guvnor.client.rpc.RepositoryServiceFactory;
import org.drools.guvnor.client.rpc.RuleAsset;
import org.drools.guvnor.client.rpc.WorkingSetConfigData;
import com.google.gwt.user.client.Command;
import java.util.ArrayList;
import org.drools.factconstraints.client.customform.CustomFormConfiguration;
import org.drools.factconstraints.client.helper.CustomFormsContainer;
/**
*
* @author esteban.aliverti@gmail.com
*/
public class WorkingSetManager {
private static WorkingSetManager INSTANCE = new WorkingSetManager();
private Map<String, Set<RuleAsset>> activeWorkingSets = new HashMap<String, Set<RuleAsset>>();
/**
* This attribute should be sever side. Maybe in some FactConstraintConfig
* object.
*/
private boolean autoVerifierEnabled = false;
public synchronized static WorkingSetManager getInstance() {
return INSTANCE;
}
/**
* Convenient method to call {@link #applyWorkingSets(java.lang.String, java.util.Set, com.google.gwt.user.client.Command) }
* when you have the WorkingSets' UUID instead of the WorkingSetConfigData
* objects
* @param packageName the package name.
* @param wsUUIDs the set of WorkingSets' UUIDs
* @param done the command to execute after the SCE and internal map are
* refreshed.
* @see #applyWorkingSets(java.lang.String, java.util.Set, com.google.gwt.user.client.Command)
*/
public void applyWorkingSets(final String packageName, final String[] wsUUIDs, final Command done) {
RepositoryServiceFactory.getService().loadRuleAssets(wsUUIDs, new GenericCallback<RuleAsset[]>() {
public void onSuccess(RuleAsset[] result) {
final Set<RuleAsset> wss = new HashSet<RuleAsset>();
wss.addAll(Arrays.asList(result));
applyWorkingSets(packageName, wss, done);
}
});
}
/**
* Applies the workingSets' valid facts to SCE. This method updates the
* internal activeWorkingSets map. If no workingSet is supplied, the
* SCE is refreshed to remove any existing filter.
* @param packageName the package name.
* @param wss the WorkingSet' assets list
* @param done the command to execute after the SCE and internal map are
* refreshed.
*/
public void applyWorkingSets(final String packageName, final Set<RuleAsset> wss, final Command done) {
this.applyWorkingSets(packageName, wss, false, done);
}
public void applyTemporalWorkingSetForFactTypes(final String packageName, final Set<String> factTypes, final Command done) {
Set<RuleAsset> workingSets = null;
if (factTypes != null && !factTypes.isEmpty()) {
//create a temporal RuleAsset to hold the fact types.
final RuleAsset workingSet = new RuleAsset();
workingSet.uuid = "workingSetMock";
WorkingSetConfigData wsConfig = new WorkingSetConfigData();
wsConfig.validFacts = factTypes.toArray(new String[factTypes.size()]);
workingSet.content = wsConfig;
workingSets = new HashSet<RuleAsset>() {{this.add(workingSet);}};
}
this.applyWorkingSets(packageName, workingSets,true, done);
}
private void applyWorkingSets(final String packageName, final Set<RuleAsset> wss, final boolean temporal, final Command done) {
Command cmd = new Command() {
public void execute() {
if (!temporal){
//update the map
activeWorkingSets.remove(packageName);
if (wss != null && !wss.isEmpty()) {
activeWorkingSets.put(packageName, wss);
}
}
if (done != null) {
done.execute();
}
}
};
if (wss == null || wss.isEmpty()) {
//if no WS, we refresh the SCE (release any filter)
SuggestionCompletionCache.getInstance().refreshPackage(packageName, cmd);
if (!temporal){
//update the map
this.activeWorkingSets.remove(packageName);
}
return;
} else {
final Set<String> validFacts = new HashSet<String>();
for (RuleAsset asset : wss) {
WorkingSetConfigData wsConfig = (WorkingSetConfigData) asset.content;
if (wsConfig.validFacts != null && wsConfig.validFacts.length > 0) {
validFacts.addAll(Arrays.asList(wsConfig.validFacts));
}
}
SuggestionCompletionCache.getInstance().applyFactFilter(packageName,
new SetFactTypeFilter(validFacts), cmd);
}
}
/**
* Returns the active WorkingSets for a package (as RuleAsset), or null if any.
* @param packageName the package name
* @return the active WorkingSets for a package (as RuleAsset), or null if any.
*/
public Set<RuleAsset> getActiveAssets(String packageName) {
return this.activeWorkingSets.get(packageName);
}
public Set<String> getActiveAssetUUIDs(String packageName) {
Set<RuleAsset> assets = this.activeWorkingSets.get(packageName);
if (assets == null) {
return null;
}
Set<String> uuids = new HashSet<String>(assets.size());
for (RuleAsset asset : assets) {
uuids.add(asset.uuid);
}
return uuids;
}
/**
* Returns the active WorkingSets for a package, or null if any.
* @param packageName the package name
* @return the active WorkingSets for a package, or null if any.
*/
public Set<WorkingSetConfigData> getActiveWorkingSets(String packageName) {
Set<RuleAsset> assets = this.activeWorkingSets.get(packageName);
if (assets == null) {
return null;
}
Set<WorkingSetConfigData> result = new HashSet<WorkingSetConfigData>();
for (RuleAsset ruleAsset : assets) {
result.add((WorkingSetConfigData) ruleAsset.content);
}
return result;
}
/**
* Returns whether the given (WorkingSet) RuleSet is active in a package or not.
* @param packageName the package name.
* @param workingSetAsset the (WorkingSet) RuleSet
* @return whether the given (WorkingSet) RuleSet is active in a package or not.
*/
public boolean isWorkingSetActive(String packageName, RuleAsset workingSetAsset) {
return this.isWorkingSetActive(packageName, workingSetAsset.uuid);
}
/**
* Returns whether the given (WorkingSet) RuleSet is active in a package or not.
* @param packageName the package name.
* @param workingSetAsset the (WorkingSet) RuleSet
* @return whether the given (WorkingSet) RuleSet is active in a package or not.
*/
public boolean isWorkingSetActive(String packageName, String ruleAssetUUID) {
if (!this.activeWorkingSets.containsKey(packageName)) {
return false;
}
Set<RuleAsset> wss = this.activeWorkingSets.get(packageName);
for (RuleAsset asset : wss) {
if (asset.uuid.equals(ruleAssetUUID)) {
return true;
}
}
return false;
}
/**
* Returns a Set of Constraints for a Fact Type's field. This method uses
* the active Working Sets of the package in order to get the Constraints.
* @param packageName the package name.
* @param factType the Fact Type (Short class name)
* @param fieldName the field name
* @return a Set of Constraints for a Fact Type's field.
*/
public Set<ConstraintConfiguration> getFieldContraints(String packageName, String factType, String fieldName) {
Set<ConstraintConfiguration> result = new HashSet<ConstraintConfiguration>();
//TODO: Change this with a centralized way of Constraint Administration.
Set<RuleAsset> activeAssets = this.getActiveAssets(packageName);
if (activeAssets != null) {
for (RuleAsset ruleAsset : activeAssets) {
List<ConstraintConfiguration> constraints = ((WorkingSetConfigData) ruleAsset.content).constraints;
if (constraints != null) {
for (ConstraintConfiguration constraint : constraints) {
if (constraint.getFactType().equals(factType) && constraint.getFieldName().equals(fieldName)) {
result.add(constraint);
}
}
}
}
}
return result;
}
/**
* TODO: We need to store/retrieve this value from repository
* @return
*/
public boolean isAutoVerifierEnabled() {
return autoVerifierEnabled;
}
/**
* TODO: We need to store/retrieve this value from repository
*/
public void setAutoVerifierEnabled(boolean autoVerifierEnabled) {
this.autoVerifierEnabled = autoVerifierEnabled;
}
/**
* Returns the associated CustomFormConfiguration for a given FactType and FieldName.
* Because CustomFormConfiguration is stored inside a WorkingSet, the
* packageName attribute is used to retrieve all the active WorkingSets.
* If more than one active WorkingSet contain a CustomFormConfiguration for
* the given FactType and FieldName the first to be found (in any specific
* nor deterministic order) will be returned.
* @param packageName the name of the package. Used to get the active
* working sets
* @param factType The short class name of the Fact Type
* @param fieldName The field name
* @return the associated CustomFormConfiguration for the given FactType and
* FieldName in the active working sets or null if any.
*/
public CustomFormConfiguration getCustomFormConfiguration(String packageName, String factType, String fieldName) {
Set<WorkingSetConfigData> packageWorkingSets = this.getActiveWorkingSets(packageName);
if (packageWorkingSets != null) {
List<CustomFormConfiguration> configs = new ArrayList<CustomFormConfiguration>();
for (WorkingSetConfigData workingSetConfigData : packageWorkingSets) {
if (workingSetConfigData.customForms != null && !workingSetConfigData.customForms.isEmpty()) {
configs.addAll(workingSetConfigData.customForms);
}
}
CustomFormsContainer cfc = new CustomFormsContainer(configs);
if (cfc.containsCustomFormFor(factType, fieldName)) {
return cfc.getCustomForm(factType, fieldName);
}
}
return null;
}
}