diff --git a/gsf-action/src/main/java/com/fatwire/gst/foundation/controller/action/support/IcsBackedObjectFactoryTemplate.java b/gsf-action/src/main/java/com/fatwire/gst/foundation/controller/action/support/IcsBackedObjectFactoryTemplate.java
index 6a0bb0d2..1a6fcccb 100644
--- a/gsf-action/src/main/java/com/fatwire/gst/foundation/controller/action/support/IcsBackedObjectFactoryTemplate.java
+++ b/gsf-action/src/main/java/com/fatwire/gst/foundation/controller/action/support/IcsBackedObjectFactoryTemplate.java
@@ -27,6 +27,7 @@
import com.fatwire.gst.foundation.facade.assetapi.asset.PreviewContext;
import com.fatwire.gst.foundation.facade.assetapi.asset.ScatteredAssetAccessTemplate;
import com.fatwire.gst.foundation.facade.assetapi.asset.TemplateAssetAccess;
+import com.fatwire.gst.foundation.facade.engage.*;
import com.fatwire.gst.foundation.facade.mda.DefaultLocaleService;
import com.fatwire.gst.foundation.facade.mda.LocaleService;
import com.fatwire.gst.foundation.facade.search.SimpleSearchEngine;
@@ -152,6 +153,20 @@ public SimpleSearchEngine createSimpleSearchEngine(final ICS ics) {
return new SimpleSearchEngine("lucene");
}
+ @ServiceProducer(cache = true)
+ public VisitorDataManagerService createVisitorDataManagerService(final ICS ics) {
+ return new VisitorDataManagerServiceImpl(ics);
+ }
+
+ @ServiceProducer(cache = true)
+ public CommerceContextService createCommerceContextService(final ICS ics) {
+ return new CommerceContextServiceImpl(ics);
+ }
+
+ @ServiceProducer(cache = true)
+ public CartService createCartService(final ICS ics) {
+ return new CartServiceImpl(ics);
+ }
@ServiceProducer(cache = false)
public NavigationService createNavigationService(final ICS ics) {
// TODO: check if unnamed association is a valid association for a Page
diff --git a/gsf-facades/src/main/java/com/fatwire/gst/foundation/facade/engage/CartService.java b/gsf-facades/src/main/java/com/fatwire/gst/foundation/facade/engage/CartService.java
new file mode 100644
index 00000000..e40e88d9
--- /dev/null
+++ b/gsf-facades/src/main/java/com/fatwire/gst/foundation/facade/engage/CartService.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2015 Function1 Inc. All rights reserved.
+ *
+ * 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 com.fatwire.gst.foundation.facade.engage;
+
+/**
+ * Facade over the WCS Engage personalization infrastructure, particularly the
+ * Cart API (CART).
+ *
+ * Note: This service will be expanded on an as-needed basis. Currently the following CART API
+ * functions are NOT yet implemented:
+ *
+ * @author Tony Field
+ * @since 2015-08-04 5:36 PM
+ */
+public interface CartService {
+}
diff --git a/gsf-facades/src/main/java/com/fatwire/gst/foundation/facade/engage/CartServiceImpl.java b/gsf-facades/src/main/java/com/fatwire/gst/foundation/facade/engage/CartServiceImpl.java
new file mode 100644
index 00000000..d088694e
--- /dev/null
+++ b/gsf-facades/src/main/java/com/fatwire/gst/foundation/facade/engage/CartServiceImpl.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2015 Function1 Inc. All rights reserved.
+ *
+ * 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 com.fatwire.gst.foundation.facade.engage;
+
+import COM.FutureTense.Interfaces.ICS;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * @author Tony Field
+ * @since 15-08-04 6:06 PM
+ */
+public class CartServiceImpl implements CartService {
+
+ private static final Log LOG = LogFactory.getLog(CartService.class);
+ private final ICS ics;
+
+ public CartServiceImpl(ICS ics) {
+ this.ics = ics;
+ LOG.trace("Created CartServiceImpl");
+ LOG.warn("Implementation is not complete");
+ }
+}
diff --git a/gsf-facades/src/main/java/com/fatwire/gst/foundation/facade/engage/CommerceContextService.java b/gsf-facades/src/main/java/com/fatwire/gst/foundation/facade/engage/CommerceContextService.java
new file mode 100644
index 00000000..865b76b0
--- /dev/null
+++ b/gsf-facades/src/main/java/com/fatwire/gst/foundation/facade/engage/CommerceContextService.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2015 Function1 Inc. All rights reserved.
+ *
+ * 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 com.fatwire.gst.foundation.facade.engage;
+
+import COM.FutureTense.Interfaces.IList;
+import com.fatwire.assetapi.data.AssetId;
+
+import java.util.List;
+
+/**
+ * Facade over the WCS Engage personalization infrastructure, particularly the
+ * Commerce Context (COMMERCECONTEXT).
+ *
+ * Not all commercecontext functions are exposed. The following APIs are NOT yet
+ * available and may be added in the future:
+ *
+ * @author Tony Field
+ * @since 15-08-04 5:36 PM
+ */
+public interface CommerceContextService {
+
+ /**
+ * Set the rating used to determine whether or not a user should be inluded in a segment or not.
+ * @param rating rating to be used as a cutoff. Must be between 1 and 100. The default value is 50.
+ */
+ void setSegmentCutoff(int rating);
+
+ /**
+ * Re-calculate segments
+ */
+ void calculateSegments();
+
+ /**
+ * Get the segments that apply to the current user
+ * Automatically calls {@link #calculateSegments()}.
+ * @return the IDs of the segments that apply to the user
+ */
+ List getSegments();
+
+ /**
+ * Return true if the visitor is in the segment specified
+ * @param id segment asset id
+ * @return true if the user is in the segment; false otherwise
+ */
+ boolean isUserInSegment(AssetId id);
+
+ /**
+ * Set the rating to be used to determine whether a promotion shall be in effect.
+ * @param rating rating to be used as a cutoff. Must be between 1 and 100. The default value is 50.
+ */
+ void setPromotionCutoff(int rating);
+
+ /**
+ * Calculate promotions in effect for the user.
+ * Automatically calls {@link #calculateSegments()}.
+ */
+ void calculatePromotions();
+
+ /**
+ * Get a list of the promotions in effect for the user.
+ * Automatically calls {@link #calculatePromotions()}.
+ * @return IList containing promotion information. Structure of the list is ....
+ */
+ IList getPromotions();
+
+
+ /**
+ * Discounts the items in the cart in accordance with
+ * any promotions in effect.
+ * Automatically calls {@link #calculatePromotions()} if
+ * they have not already been calculated.
+ */
+ void discountCart();
+
+
+ /**
+ * Discount items in the specified temporary cart against any items
+ * currently being promoted. This is typically used when trying to get the
+ * discount amount applied to a particular item.
+ * Automatically calls {@link #calculatePromotions()} if
+ * they have not already been calculated.
+ * @param cartName temp cart name
+ */
+ void discountTempCart(String cartName);
+
+ /**
+ * Extract a COPY of the current cart and make it available in the request context. This cart
+ * is not attached to the visitor context. It's possible to alter this cart though, and then
+ * set it back into the visitor context using {@link #setCurrentCart(String)}
+ * @param cartName name to be used for the working copy of the cart
+ */
+ void getCurrentCart(String cartName);
+
+ /**
+ * Set the working copy of the cart back into the visitor context.
+ * @param cartName name of the working copy of the cart
+ */
+ void setCurrentCart(String cartName);
+
+ /**
+ * Access the ratings associated with the assets specified. This method is used primarily for debug purposes.
+ * @param assets list of asset ids to have their ratings checked
+ * @param defaultRating rating to use for assets that don't have one.
+ * The default is 50. Must be a number between 1 and 100.
+ * @return IList containing 3 columns - assettype, assetid, rating,
+ * all sorted according to the ratings of the assets.
+ */
+ IList getRatings(List assets, int defaultRating);
+
+ /**
+ * Return a single recommended asset from the recommendation specified.
+ * This is a convenience version of the {@link #getRecommendations(AssetId,List,boolean,int,String,int,String,IList)} method.
+ * @param recId recommendation asset id to be used. If a promotion is in
+ * effect, the promotion id is used instead.
+ * @return recommended asset, or null if none found.
+ */
+ AssetId getRecommendation(AssetId recId);
+ /**
+ * Return a single recommended asset from the recommendation specified.
+ * This is a convenience version of the {@link #getRecommendations(String,List,boolean,int,String,int,String,IList)} method.
+ * @param recName recommendation asset name. If a promotion is in effect,
+ * the promotion name is used instead.
+ * @return recommended asset, or null if none found.
+ */
+ AssetId getRecommendation(String recName);
+
+ /**
+ * Get recommended assets for the specified recommendation.
+ * This is a convenience version of the {@link #getRecommendations(AssetId,List,boolean,int,String,int,String,IList)} method.
+ *
+ * @param recId recommendation asset id to be used, or if a promotion is in effect, the promotion name.
+ * @param assetsForContext input asset list for context-specific (related-item) recommendations
+ * @param doFilter true to exclude the assets for context-based (related-item) recommendations
+ * @param maxCount maximum number of assets to return
+ * @return recommended assets.
+ */
+ List getRecommendations(AssetId recId,
+ List assetsForContext,
+ boolean doFilter,
+ int maxCount);
+
+ /**
+ * Get recommended assets for the specified recommendation.
+ * @param recId recommendation asset id to be used, or if a promotion is in effect, the promotion name.
+ * @param assetsForContext input asset list for context-specific (related-item) recommendations
+ * @param doFilter true to exclude the assets for context-based (related-item) recommendations
+ * @param maxCount maximum number of assets to return
+ * @param doFilter true to exclude the assets for context-based recommendations
+ * (related item recommendations)
+ * @param depType dependency type to be used for this recommendation. Default value
+ * is "unknown". If no promotions that are allowed to override
+ * recommendations are in effect, then "exact" and "exist" values are
+ * allowed, but if promotions are allowed to override the recommendation,
+ * then this value is ignored and the value of "unknown" is used.
+ * @param engine the name of the engine used to optimize the recommendation.
+ * Used in conjunction with the engineParams param - typically rtd if overridden
+ * at all. May be null.
+ * @param engineParams a list of params that are passed to the engine. May be null if engine is null.
+ * @return recommended assets.
+ */
+ List getRecommendations(AssetId recId,
+ List assetsForContext,
+ boolean doFilter,
+ int maxCount,
+ String depType,
+ int defaultRating,
+ String engine,
+ IList engineParams);
+
+
+ /**
+ * Get recommended assets for the specified recommendation.
+ * @param recName the name of the recommendation to use, or if a promotion is in effect that
+ * overrides this recommendation, the promotion name.
+ * @param assetsForContext input asset list for context-specific (related-item) recommendations
+ * @param doFilter true to exclude the assets for context-based (related-item) recommendations
+ * @param maxCount maximum number of assets to return
+ * @param doFilter true to exclude the assets for context-based recommendations
+ * (related item recommendations)
+ * @param depType dependency type to be used for this recommendation. Default value
+ * is "unknown". If no promotions that are allowed to override
+ * recommendations are in effect, then "exact" and "exist" values are
+ * allowed, but if promotions are allowed to override the recommendation,
+ * then this value is ignored and the value of "unknown" is used.
+ * @param engine the name of the engine used to optimize the recommendation.
+ * Used in conjunction with the engineParams param - typically rtd if overridden
+ * at all.
+ * @param engineParams a list of params that are passed to the engine.
+ * @return recommended assets.
+ */
+ List getRecommendations(String recName,
+ List assetsForContext,
+ boolean doFilter,
+ int maxCount,
+ String depType,
+ int defaultRating,
+ String engine,
+ IList engineParams);
+
+ /**
+ * Logs the user out of the visitor context, dissociating the user's id from the visitor context.
+ */
+ void logout();
+
+}
diff --git a/gsf-facades/src/main/java/com/fatwire/gst/foundation/facade/engage/CommerceContextServiceImpl.java b/gsf-facades/src/main/java/com/fatwire/gst/foundation/facade/engage/CommerceContextServiceImpl.java
new file mode 100644
index 00000000..de746571
--- /dev/null
+++ b/gsf-facades/src/main/java/com/fatwire/gst/foundation/facade/engage/CommerceContextServiceImpl.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2015 Function1 Inc. All rights reserved.
+ *
+ * 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 com.fatwire.gst.foundation.facade.engage;
+
+import COM.FutureTense.Interfaces.ICS;
+import COM.FutureTense.Interfaces.IList;
+import com.fatwire.assetapi.data.AssetId;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.util.List;
+
+/**
+ * @author Tony Field
+ * @since 15-08-04 6:06 PM
+ */
+public class CommerceContextServiceImpl implements CommerceContextService {
+
+ private static final Log LOG = LogFactory.getLog(CommerceContextService.class);
+ private final ICS ics;
+
+ public CommerceContextServiceImpl(ICS ics) {
+ this.ics = ics;
+ LOG.trace("Created CommerceContextServiceImpl");
+ LOG.warn("Implementation is not complete");
+ }
+
+ @Override
+ public void setSegmentCutoff(int rating) {
+ // todo: implement
+ }
+
+ @Override
+ public void calculateSegments() {
+ // todo: implement
+ }
+
+ @Override
+ public List getSegments() {
+ // todo: implement
+ return null;
+ }
+
+ @Override
+ public boolean isUserInSegment(AssetId id) {
+ // todo: implement
+ return false;
+ }
+
+ @Override
+ public void setPromotionCutoff(int rating) {
+ // todo: implement
+ }
+
+ @Override
+ public void calculatePromotions() {
+ // todo: implement
+ }
+
+ @Override
+ public IList getPromotions() {
+ // todo: implement
+ return null;
+ }
+
+ @Override
+ public void discountCart() {
+ // todo: implement
+ }
+
+ @Override
+ public void discountTempCart(String cartName) {
+ // todo: implement
+ }
+
+ @Override
+ public void getCurrentCart(String cartName) {
+ // todo: implement
+ }
+
+ @Override
+ public void setCurrentCart(String cartName) {
+ // todo: implement
+ }
+
+ @Override
+ public IList getRatings(List assets, int defaultRating) {
+ // todo: implement
+ return null;
+ }
+
+ @Override
+ public AssetId getRecommendation(AssetId recId) {
+ // todo: implement
+ return null;
+ }
+
+ @Override
+ public AssetId getRecommendation(String recName) {
+ // todo: implement
+ return null;
+ }
+
+ @Override
+ public List getRecommendations(AssetId recId, List assetsForContext, boolean doFilter, int maxCount) {
+ // todo: implement
+ return null;
+ }
+
+ @Override
+ public List getRecommendations(AssetId recId, List assetsForContext, boolean doFilter, int maxCount, String depType, int defaultRating, String engine, IList engineParams) {
+ // todo: implement
+ return null;
+ }
+
+ @Override
+ public List getRecommendations(String recName, List assetsForContext, boolean doFilter, int maxCount, String depType, int defaultRating, String engine, IList engineParams) {
+ // todo: implement
+ return null;
+ }
+
+ @Override
+ public void logout() {
+ // todo: implement
+ }
+}
diff --git a/gsf-facades/src/main/java/com/fatwire/gst/foundation/facade/engage/VisitorDataManagerService.java b/gsf-facades/src/main/java/com/fatwire/gst/foundation/facade/engage/VisitorDataManagerService.java
new file mode 100644
index 00000000..0bf0e38d
--- /dev/null
+++ b/gsf-facades/src/main/java/com/fatwire/gst/foundation/facade/engage/VisitorDataManagerService.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2015 Function1 Inc. All rights reserved.
+ *
+ * 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 com.fatwire.gst.foundation.facade.engage;
+
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * Facade over the WCS Engage personalization infrastructure, particularly the
+ * Visitor Data Manager (VDM).
+ *
+ * Note this facade does not implement all methods of the VDM API. The following methods
+ * are not yet implemented and may be added in the future:
+ *
+ *
+ * @author Tony Field
+ * @since 15-08-04 5:36 PM
+ */
+public interface VisitorDataManagerService {
+
+ /**
+ * Set the alias string for the visitor. Does not re-set if no
+ * change in the alias value (checks first).
+ * @param name alias name (e.g. userid, tracker-cookie)
+ * @param value alias value
+ */
+ void setAlias(String name, String value);
+
+ /**
+ * Retrieve the value for the specified alias.
+ * @param name alias name
+ * @return value if set
+ */
+ String getAlias(String name);
+
+ /**
+ * Set a visitor attribute into the visitor context. Does not re-set if no change
+ * in the attribute value (checks first).
+ * @param name attribute name
+ * @param value attribute value
+ */
+ void setScalar(String name, String value);
+
+ /**
+ * Get the attribute value corresponding to the name sepcified.
+ * @param name the attribute name
+ * @return the attribute value
+ */
+ String getScalar(String name);
+
+ /**
+ * Save the object in the visitor repository. Useful for saving shopping carts.
+ * @param name name of the object
+ * @param value object value - must implement either Serializable or IStorableObject
+ */
+ void saveScalarObject(String name, Object value);
+
+ /**
+ * Retrieve the visitor object. Useful for retrieving shopping carts
+ * @param name object name
+ * @return visitor object value
+ */
+ Object loadScalarObject(String name);
+
+
+ /**
+ * Save a time-stamped attribute to the visitor context. This is
+ * a convenience version of {@link #recordHistory(String,Map)}.
+ * @param definition the name of the history definition to be used
+ * @param name name of the history attribute to be stored
+ * @param value value of the history attribute to be stored
+ */
+ void recordHistory(String definition, String name, Object value);
+
+ /**
+ * Save a time-stamped attribute to the visitor context
+ * @param definition the name of the history definition to be used
+ * @param values map containing the values to set into the history record
+ */
+ void recordHistory(String definition, Map values);
+
+ /**
+ * Remove data recorded for visitors who have not returned to the
+ * site in the specified period of time. Long-running maintenance task.
+ * Not for website delivery use.
+ * @param cutoff visitor data will be saved for visitors who have visited
+ * the site after this date.
+ */
+ void flushInactive(Date cutoff);
+
+ /**
+ * Consolidate visitor data for visitor sessions that haven't been
+ * active since the cutoff date, that are linked together using the
+ * alias mechanism. Long-running maintenance task. Not for website
+ * delivery use.
+ * @param cutoff Visitor sessions last active before this date will
+ * be merged together if linked using aliases.
+ */
+ void mergeInactive(Date cutoff);
+
+}
diff --git a/gsf-facades/src/main/java/com/fatwire/gst/foundation/facade/engage/VisitorDataManagerServiceImpl.java b/gsf-facades/src/main/java/com/fatwire/gst/foundation/facade/engage/VisitorDataManagerServiceImpl.java
new file mode 100644
index 00000000..dc642d8b
--- /dev/null
+++ b/gsf-facades/src/main/java/com/fatwire/gst/foundation/facade/engage/VisitorDataManagerServiceImpl.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2015 Function1 Inc. All rights reserved.
+ *
+ * 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 com.fatwire.gst.foundation.facade.engage;
+
+import COM.FutureTense.Interfaces.ICS;
+import com.fatwire.gst.foundation.facade.ilist.TwoColumnIList;
+import com.fatwire.gst.foundation.facade.runtag.vdm.*;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * @author Tony Field
+ * @since 15-08-04 6:07 PM
+ */
+public class VisitorDataManagerServiceImpl implements VisitorDataManagerService {
+
+ private static final Log LOG = LogFactory.getLog(VisitorDataManagerService.class);
+ private final ICS ics;
+
+ public VisitorDataManagerServiceImpl(ICS ics) {
+ this.ics = ics;
+ LOG.trace("Created VisitorDataManagerServiceImpl");
+ LOG.warn("Implementation is not complete");
+ }
+
+ @Override
+ public void setAlias(String name, String value) {
+ SetAliasWithoutReset tag = new SetAliasWithoutReset(name, value);
+ tag.execute(ics);
+ }
+
+ @Override
+ public String getAlias(String name) {
+ String var = "getalias_" + ics.genID(false);
+ GetAlias tag = new GetAlias(name, var);
+ try {
+ tag.execute(ics);
+ return ics.GetVar(var);
+ } finally {
+ ics.RemoveVar(var); // unregister
+ }
+ }
+
+ @Override
+ public void setScalar(String name, String value) {
+ SetScalarWithoutReset tag = new SetScalarWithoutReset(name, value);
+ tag.execute(ics);
+ }
+
+ @Override
+ public String getScalar(String name) {
+ String var = "getscalar_" + ics.genID(false);
+ GetScalar tag = new GetScalar(name, var);
+ try {
+ tag.execute(ics);
+ return ics.GetVar(var);
+ } finally {
+ ics.RemoveVar(var);
+ }
+ }
+
+ @Override
+ public void saveScalarObject(String name, Object value) {
+ String var = "saveScalar_" + ics.genID(false);
+ try {
+ ics.SetObj(var, value);
+ SaveScalarObject tag = new SaveScalarObject();
+ tag.setAttribute(name);
+ tag.setObject(var);
+ tag.execute(ics);
+ } finally {
+ ics.SetObj(var, null);
+ }
+ }
+
+ @Override
+ public Object loadScalarObject(String name) {
+ String var = "loadscalar_" + ics.genID(false);
+ try {
+ LoadScalarObject tag = new LoadScalarObject(name, var);
+ tag.execute(ics);
+ return ics.GetObj(var);
+ } finally {
+ ics.SetObj(var, null);
+ }
+ }
+
+ @Override
+ public void recordHistory(String definition, String name, Object value) {
+ String listName = "recordHistory_" + ics.genID(false);
+ TwoColumnIList list = new TwoColumnIList(listName, "field", "value");
+ list.addRow(name, value);
+ try {
+ ics.RegisterList(listName, list);
+ RecordHistory tag = new RecordHistory(definition, listName);
+ tag.execute(ics);
+ } finally {
+ ics.RegisterList(listName, null);
+ }
+ }
+
+ @Override
+ public void recordHistory(String definition, Map values) {
+ String listName = "recordHistory_" + ics.genID(false);
+ TwoColumnIList list = new TwoColumnIList(listName, "field", "value");
+ for (String key : values.keySet()) {
+ list.addRow(key, values.get(key));
+ }
+ try {
+ ics.RegisterList(listName, list);
+ RecordHistory tag = new RecordHistory(definition, listName);
+ tag.execute(ics);
+ } finally {
+ ics.RegisterList(listName, null);
+ }
+ }
+
+ @Override
+ public void flushInactive(Date cutoff) {
+ FlushInactive tag = new FlushInactive();
+ tag.setStartdate(cutoff);
+ tag.execute(ics);
+ }
+
+ @Override
+ public void mergeInactive(Date cutoff) {
+ MergeInactive tag = new MergeInactive();
+ tag.setStartdate(cutoff);
+ tag.execute(ics);
+ }
+}
diff --git a/gsf-facades/src/main/java/com/fatwire/gst/foundation/facade/ilist/TwoColumnIList.java b/gsf-facades/src/main/java/com/fatwire/gst/foundation/facade/ilist/TwoColumnIList.java
new file mode 100644
index 00000000..8a5d93a2
--- /dev/null
+++ b/gsf-facades/src/main/java/com/fatwire/gst/foundation/facade/ilist/TwoColumnIList.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2015 Function1 Inc. All rights reserved.
+ *
+ * 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 com.fatwire.gst.foundation.facade.ilist;
+
+import COM.FutureTense.Interfaces.IList;
+import com.fatwire.gst.foundation.facade.sql.AbstractIList;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Tony Field
+ * @since 2015-08-04 10:00 PM
+ */
+public class TwoColumnIList extends AbstractIList {
+
+ private final String col1Name;
+ private final String col2Name;
+ private final List