- Refinements to Javascript/Freemarker Node conversions

- Removed hard-coded conversions from Web Scripts
- example category search web script aligned with documentation

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5940 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
David Caruana
2007-06-13 17:23:47 +00:00
parent 80939c8187
commit 2794a59085
5 changed files with 114 additions and 83 deletions

View File

@@ -1,8 +1,8 @@
<webscript> <webscript>
<shortname>Category Search</shortname> <shortname>Category Search</shortname>
<description>Find all blog entries tagged with specified categories</description> <description>Find all blog entries tagged with specified categories</description>
<url>/sample/blog/category?c={category}</url> <url>/sample/blog/category/{category}</url>
<url>/sample/blog/category.atom?c={category}</url> <format default="html">argument</format>
<authentication>guest</authentication> <authentication>guest</authentication>
<transaction>required</transaction> <transaction>required</transaction>
</webscript> </webscript>

View File

@@ -1,2 +1,2 @@
var nodes = search.luceneSearch("PATH:\"/cm:generalclassifiable//cm:" + args.c + "//member\""); var nodes = search.luceneSearch("PATH:\"/cm:generalclassifiable//cm:" + url.extension + "//member\"");
model.resultset = nodes; model.resultset = nodes;

View File

@@ -72,7 +72,7 @@ public class RhinoScriptProcessor extends BaseProcessor implements ScriptProcess
private static final String SCRIPT_ROOT = "_root"; private static final String SCRIPT_ROOT = "_root";
/** Base Value Converter */ /** Base Value Converter */
private ValueConverter valueConverter = new ReturnValueConverter(); private ValueConverter valueConverter = new ValueConverter();
/** Store into which to resolve cm:name based script paths */ /** Store into which to resolve cm:name based script paths */
private StoreRef storeRef; private StoreRef storeRef;
@@ -510,19 +510,7 @@ public class RhinoScriptProcessor extends BaseProcessor implements ScriptProcess
Object result = cx.evaluateString(scope, script, "AlfrescoScript", 1, null); Object result = cx.evaluateString(scope, script, "AlfrescoScript", 1, null);
// extract java object result if wrapped by Rhino // extract java object result if wrapped by Rhino
if (result instanceof Serializable) result = valueConverter.convertValueForRepo((Serializable)result);
{
result = valueConverter.convertValueForRepo((Serializable)result);
}
else if (result instanceof Wrapper)
{
result = ((Wrapper)result).unwrap();
}
else if (result instanceof NativeArray)
{
result = Context.jsToJava(result, Object[].class);
}
return result; return result;
} }
catch (Throwable err) catch (Throwable err)
@@ -565,29 +553,4 @@ public class RhinoScriptProcessor extends BaseProcessor implements ScriptProcess
return newModel; return newModel;
} }
/**
* Value conversion for handling Javascript return values.
*/
public class ReturnValueConverter extends ValueConverter
{
/**
* Convert an object from any script wrapper value to a valid repository serializable value.
* This includes converting JavaScript Array objects to Lists of valid objects.
*
* @param value Value to convert from script wrapper object to repo serializable value
*
* @return valid repo value
*/
public Serializable convertValueForRepo(Serializable value)
{
if (value instanceof Wrapper ||
value instanceof ScriptableObject ||
value instanceof Serializable[])
{
value = super.convertValueForRepo(value);
}
return value;
}
}
} }

View File

@@ -28,7 +28,9 @@ import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import org.alfresco.service.ServiceRegistry; import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.AssociationRef;
@@ -37,6 +39,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.mozilla.javascript.Context; import org.mozilla.javascript.Context;
import org.mozilla.javascript.IdScriptableObject;
import org.mozilla.javascript.NativeArray; import org.mozilla.javascript.NativeArray;
import org.mozilla.javascript.ScriptRuntime; import org.mozilla.javascript.ScriptRuntime;
import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.Scriptable;
@@ -153,26 +156,50 @@ public class ValueConverter
// set using a JavaScript Array object // set using a JavaScript Array object
ScriptableObject values = (ScriptableObject)value; ScriptableObject values = (ScriptableObject)value;
if (value instanceof NativeArray) if (value instanceof IdScriptableObject)
{ {
// convert JavaScript array of values to a List of Serializable objects if (value instanceof NativeArray)
Object[] propIds = values.getIds();
List<Serializable> propValues = new ArrayList<Serializable>(propIds.length);
for (int i=0; i<propIds.length; i++)
{ {
// work on each key in turn // convert JavaScript array of values to a List of Serializable objects
Object propId = propIds[i]; Object[] propIds = values.getIds();
List<Serializable> propValues = new ArrayList<Serializable>(propIds.length);
// we are only interested in keys that indicate a list of values for (int i=0; i<propIds.length; i++)
if (propId instanceof Integer)
{ {
// get the value out for the specified key // work on each key in turn
Serializable val = (Serializable)values.get((Integer)propId, values); Object propId = propIds[i];
// recursively call this method to convert the value
propValues.add(convertValueForRepo(val)); // we are only interested in keys that indicate a list of values
if (propId instanceof Integer)
{
// get the value out for the specified key
Serializable val = (Serializable)values.get((Integer)propId, values);
// recursively call this method to convert the value
propValues.add(convertValueForRepo(val));
}
} }
value = (Serializable)propValues;
}
else
{
// convert JavaScript map to values to a Map of Serializable objects
Object[] propIds = values.getIds();
Map<String, Serializable> propValues = new HashMap<String, Serializable>(propIds.length);
for (int i=0; i<propIds.length; i++)
{
// work on each key in turn
Object propId = propIds[i];
// we are only interested in keys that indicate a list of values
if (propId instanceof String)
{
// get the value out for the specified key
Serializable val = (Serializable)values.get((String)propId, values);
// recursively call this method to convert the value
propValues.put((String)propId, convertValueForRepo(val));
}
}
value = (Serializable)propValues;
} }
value = (Serializable)propValues;
} }
else else
{ {

View File

@@ -25,8 +25,11 @@
package org.alfresco.repo.template; package org.alfresco.repo.template;
import java.io.IOException; import java.io.IOException;
import java.io.Serializable;
import java.io.Writer; import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import org.alfresco.repo.processor.BaseProcessor; import org.alfresco.repo.processor.BaseProcessor;
@@ -286,26 +289,6 @@ public class FreeMarkerProcessor extends BaseProcessor implements TemplateProces
// Look for the image resolver in the model // Look for the image resolver in the model
TemplateImageResolver imageResolver = (TemplateImageResolver)((Map)model).get(TemplateService.KEY_IMAGE_RESOLVER); TemplateImageResolver imageResolver = (TemplateImageResolver)((Map)model).get(TemplateService.KEY_IMAGE_RESOLVER);
for (Object objKey : ((Map)model).keySet())
{
String key = (String)objKey;
if (key.equals(TemplateService.KEY_IMAGE_RESOLVER) == false)
{
Object value = ((Map)model).get(key);
if (value instanceof NodeRef)
{
// Concer the node reference to a template node
freeMarkerModel.put(key, new TemplateNode((NodeRef)value, this.services, imageResolver));
}
else
{
// Just add the object to the free marker model
freeMarkerModel.put(key, ((Map)model).get(key));
}
}
}
// add the template extensions to the model // add the template extensions to the model
// the extensions include custom root helper objects and custom template method objects // the extensions include custom root helper objects and custom template method objects
for (ProcessorExtension ext : this.processorExtensions.values()) for (ProcessorExtension ext : this.processorExtensions.values())
@@ -317,11 +300,69 @@ public class FreeMarkerProcessor extends BaseProcessor implements TemplateProces
freeMarkerModel.put(ext.getExtensionName(), ext); freeMarkerModel.put(ext.getExtensionName(), ext);
} }
Map<String, Object> value = (Map<String, Object>)convertValue(model, imageResolver);
freeMarkerModel.putAll(value);
return freeMarkerModel; return freeMarkerModel;
} }
else else
{ {
return model; return convertValue(model, null);
} }
} }
/**
* Converts a value to a freemarker value
*
* @param value
* @param imageResolver
* @return
*/
private Object convertValue(Object value, TemplateImageResolver imageResolver)
{
if (value instanceof NodeRef)
{
return new TemplateNode((NodeRef)value, this.services, imageResolver);
}
else if (value instanceof Map)
{
Map<String, Object> map = (Map<String, Object>)value;
Map<String, Object> convertedMap = new HashMap<String, Object>(map.size());
for (String key : map.keySet())
{
if (key.equals(TemplateService.KEY_IMAGE_RESOLVER) == false)
{
Object mapValue = map.get(key);
convertedMap.put(key, convertValue(mapValue, imageResolver));
}
}
return convertedMap;
}
else if (value instanceof List)
{
List<Object> list = (List<Object>)value;
List<Object> convertedList = new ArrayList<Object>(list.size());
for (Object listVal : list)
{
convertedList.add(convertValue(listVal, imageResolver));
}
return convertedList;
}
else if (value instanceof Object[])
{
Object[] array = (Object[])value;
Object[] convertedArray = new Object[array.length];
int i = 0;
for (Object item : array)
{
convertedArray[i++] = convertValue(item, imageResolver);
}
return convertedArray;
}
return value;
}
} }