. JavaScript API improvements

. Template API improvements
. Fixed a couple more UTF-8 code file warnings when compiling the source

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@3473 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Kevin Roast
2006-08-09 12:51:42 +00:00
parent e7e4efb6c0
commit d24a815b79
8 changed files with 183 additions and 42 deletions

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005 Jesper Steen M<EFBFBD>ller * Copyright (C) 2005 Jesper Steen Møller
* *
* Licensed under the Mozilla Public License version 1.1 * Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a * with a permitted attribution clause. You may obtain a
@@ -43,7 +43,7 @@ import org.alfresco.service.namespace.QName;
* otherwise they are left as is.<br/> * otherwise they are left as is.<br/>
* <i>This may change if the action gets parameterized in future</i>. * <i>This may change if the action gets parameterized in future</i>.
* *
* @author Jesper Steen M<EFBFBD>ller * @author Jesper Steen Møller
*/ */
public class ContentMetadataExtracter extends ActionExecuterAbstractBase public class ContentMetadataExtracter extends ActionExecuterAbstractBase
{ {

View File

@@ -25,8 +25,6 @@ import org.alfresco.repo.content.MimetypeMap;
*/ */
public class HtmlParserContentTransformerTest extends AbstractContentTransformerTest public class HtmlParserContentTransformerTest extends AbstractContentTransformerTest
{ {
private static final String SOME_CONTENT = "azAz10!<21>$%^&*()\t\r\n";
private ContentTransformer transformer; private ContentTransformer transformer;
@Override @Override

View File

@@ -21,6 +21,7 @@ import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@@ -405,33 +406,8 @@ public final class Node implements Serializable, Scopeable
{ {
Serializable propValue = props.get(qname); Serializable propValue = props.get(qname);
// perform conversions from Java objects to JavaScript scriptable instances // perform the conversion to a script safe value and store
if (propValue instanceof NodeRef) this.properties.put(qname.toString(), convertValueForScript(qname, propValue));
{
// NodeRef object properties are converted to new Node objects
// so they can be used as objects within a template
propValue = new Node(
((NodeRef)propValue), this.services, this.imageResolver, this.scope);
}
else if (propValue instanceof ContentData)
{
// ContentData object properties are converted to ScriptContentData objects
// so the content and other properties of those objects can be accessed
propValue = new ScriptContentData((ContentData)propValue, qname);
}
else if (propValue instanceof Date)
{
// convert Date to JavaScript native Date object
// call the "Date" constructor on the root scope object - passing in the millisecond
// value from the Java date - this will construct a JavaScript Date with the same value
Date date = (Date)propValue;
Object val = ScriptRuntime.newObject(
Context.getCurrentContext(), this.scope, "Date", new Object[] {date.getTime()});
propValue = (Serializable)val;
}
// simple numbers and strings are handled automatically by Rhino
this.properties.put(qname.toString(), propValue);
} }
} }
@@ -924,7 +900,7 @@ public final class Node implements Serializable, Scopeable
Serializable value = (Serializable)this.properties.get(key); Serializable value = (Serializable)this.properties.get(key);
// perform the conversion from script wrapper object to repo serializable values // perform the conversion from script wrapper object to repo serializable values
value = convertValue(value); value = convertValueForRepo(value);
props.put(createQName(key), value); props.put(createQName(key), value);
} }
@@ -939,9 +915,13 @@ public final class Node implements Serializable, Scopeable
* *
* @return valid repo value * @return valid repo value
*/ */
private static Serializable convertValue(Serializable value) private static Serializable convertValueForRepo(Serializable value)
{ {
if (value instanceof Node) if (value == null)
{
return null;
}
else if (value instanceof Node)
{ {
// convert back to NodeRef // convert back to NodeRef
value = ((Node)value).getNodeRef(); value = ((Node)value).getNodeRef();
@@ -955,7 +935,7 @@ public final class Node implements Serializable, Scopeable
{ {
// unwrap a Java object from a JavaScript wrapper // unwrap a Java object from a JavaScript wrapper
// recursively call this method to convert the unwrapped value // recursively call this method to convert the unwrapped value
value = convertValue((Serializable)((Wrapper)value).unwrap()); value = convertValueForRepo((Serializable)((Wrapper)value).unwrap());
} }
else if (value instanceof ScriptableObject) else if (value instanceof ScriptableObject)
{ {
@@ -979,7 +959,7 @@ public final class Node implements Serializable, Scopeable
// get the value out for the specified key // get the value out for the specified key
Serializable val = (Serializable)values.get((Integer)propId, values); Serializable val = (Serializable)values.get((Integer)propId, values);
// recursively call this method to convert the value // recursively call this method to convert the value
propValues.add(convertValue(val)); propValues.add(convertValueForRepo(val));
} }
} }
value = (Serializable)propValues; value = (Serializable)propValues;
@@ -997,6 +977,61 @@ public final class Node implements Serializable, Scopeable
return value; return value;
} }
/**
* Convert an object from any repository serialized value to a valid script object.
* This includes converting Collection multi-value properties into JavaScript Array objects.
*
* @param qname QName of the property value for conversion
* @param value Property value
*
* @return Value safe for scripting usage
*/
private Serializable convertValueForScript(QName qname, Serializable value)
{
// perform conversions from Java objects to JavaScript scriptable instances
if (value == null)
{
return null;
}
else if (value instanceof NodeRef)
{
// NodeRef object properties are converted to new Node objects
// so they can be used as objects within a template
value = new Node(((NodeRef)value), this.services, this.imageResolver, this.scope);
}
else if (value instanceof ContentData)
{
// ContentData object properties are converted to ScriptContentData objects
// so the content and other properties of those objects can be accessed
value = new ScriptContentData((ContentData)value, qname);
}
else if (value instanceof Date)
{
// convert Date to JavaScript native Date object
// call the "Date" constructor on the root scope object - passing in the millisecond
// value from the Java date - this will construct a JavaScript Date with the same value
Date date = (Date)value;
Object val = ScriptRuntime.newObject(
Context.getCurrentContext(), this.scope, "Date", new Object[] {date.getTime()});
value = (Serializable)val;
}
else if (value instanceof Collection)
{
// recursively convert each value in the collection
Collection<Serializable> collection = (Collection<Serializable>)value;
Serializable[] array = new Serializable[collection.size()];
int index = 0;
for (Serializable obj : collection)
{
array[index++] = convertValueForScript(qname, obj);
}
value = array;
}
// simple numbers and strings are wrapped automatically by Rhino
return value;
}
/** /**
* Re-sets the type of the node. Can be called in order specialise a node to a sub-type. * Re-sets the type of the node. Can be called in order specialise a node to a sub-type.
* *
@@ -1300,7 +1335,7 @@ public final class Node implements Serializable, Scopeable
{ {
// get the value out for the specified key - make sure it is Serializable // get the value out for the specified key - make sure it is Serializable
Object value = props.get((String)propId, props); Object value = props.get((String)propId, props);
value = convertValue((Serializable)value); value = convertValueForRepo((Serializable)value);
aspectProps.put(createQName((String)propId), (Serializable)value); aspectProps.put(createQName((String)propId), (Serializable)value);
} }
} }
@@ -1502,19 +1537,22 @@ public final class Node implements Serializable, Scopeable
if (reader != null) if (reader != null)
{ {
// Copy the content node to a new node // Copy the content node to a new node
String copyName = TransformActionExecuter.transformName(
this.services.getMimetypeService(), getName(), mimetype);
NodeRef copyNodeRef = this.services.getCopyService().copy( NodeRef copyNodeRef = this.services.getCopyService().copy(
this.nodeRef, this.nodeRef,
destination, destination,
ContentModel.ASSOC_CONTAINS, ContentModel.ASSOC_CONTAINS,
getPrimaryParentAssoc().getQName(), QName.createQName(
ContentModel.PROP_CONTENT.getNamespaceURI(),
QName.createValidLocalName(copyName)),
false); false);
// modify the name of the copy to reflect the new mimetype // modify the name of the copy to reflect the new mimetype
this.nodeService.setProperty( this.nodeService.setProperty(
copyNodeRef, copyNodeRef,
ContentModel.PROP_NAME, ContentModel.PROP_NAME,
TransformActionExecuter.transformName( copyName);
this.services.getMimetypeService(), getName(), mimetype));
// get the writer and set it up // get the writer and set it up
ContentWriter writer = contentService.getWriter(copyNodeRef, ContentModel.PROP_CONTENT, true); ContentWriter writer = contentService.getWriter(copyNodeRef, ContentModel.PROP_CONTENT, true);

View File

@@ -80,6 +80,40 @@ public final class Search implements Scopeable
this.scope = scope; this.scope = scope;
} }
/**
* Find a single Node by the Node reference
*
* @param ref The NodeRef of the Node to find
*
* @return the Node if found or null if failed to find
*/
public Node findNode(NodeRef ref)
{
return findNode(ref.toString());
}
/**
* Find a single Node by the Node reference
*
* @param ref The fully qualified NodeRef in String format
*
* @return the Node if found or null if failed to find
*/
public Node findNode(String ref)
{
String query = ref.replace(":", "\\:");
query = query.replace("/", "\\/");
Node[] result = query("ID:" + query);
if (result.length == 1)
{
return result[0];
}
else
{
return null;
}
}
/** /**
* Execute a Lucene search * Execute a Lucene search
* *

View File

@@ -28,7 +28,7 @@ import org.alfresco.service.cmr.repository.TemplateNode;
* *
* @author Kevin Roast * @author Kevin Roast
*/ */
public final class NamePathResultsMap extends BasePathResultsMap public class NamePathResultsMap extends BasePathResultsMap
{ {
/** /**
* Constructor * Constructor

View File

@@ -0,0 +1,62 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.repo.template;
import java.util.List;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.TemplateNode;
/**
* Provides functionality to execute a Lucene search for a single node by NodeRef.
*
* @author Kevin Roast
*/
public class NodeSearchResultsMap extends BaseSearchResultsMap
{
/**
* Constructor
*
* @param parent The parent TemplateNode to execute searches from
* @param services The ServiceRegistry to use
*/
public NodeSearchResultsMap(TemplateNode parent, ServiceRegistry services)
{
super(parent, services);
}
/**
* @see org.alfresco.repo.template.BaseTemplateMap#get(java.lang.Object)
*/
public Object get(Object key)
{
TemplateNode result = null;
if (key != null)
{
String ref = key.toString().replace(":", "\\:");
ref = ref.replace("/", "\\/");
List<TemplateNode> results = query(ref);
if (results.size() == 1)
{
result = results.get(0);
}
}
return result;
}
}

View File

@@ -25,7 +25,7 @@ import org.alfresco.service.cmr.repository.TemplateNode;
* *
* @author Kevin Roast * @author Kevin Roast
*/ */
public final class XPathResultsMap extends BasePathResultsMap public class XPathResultsMap extends BasePathResultsMap
{ {
/** /**
* Constructor * Constructor

View File

@@ -30,6 +30,7 @@ import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.permissions.AccessDeniedException; import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.repo.template.LuceneSearchResultsMap; import org.alfresco.repo.template.LuceneSearchResultsMap;
import org.alfresco.repo.template.NamePathResultsMap; import org.alfresco.repo.template.NamePathResultsMap;
import org.alfresco.repo.template.NodeSearchResultsMap;
import org.alfresco.repo.template.SavedSearchResultsMap; import org.alfresco.repo.template.SavedSearchResultsMap;
import org.alfresco.repo.template.XPathResultsMap; import org.alfresco.repo.template.XPathResultsMap;
import org.alfresco.service.ServiceRegistry; import org.alfresco.service.ServiceRegistry;
@@ -235,6 +236,14 @@ public final class TemplateNode implements Serializable
return new LuceneSearchResultsMap(this, this.services); return new LuceneSearchResultsMap(this, this.services);
} }
/**
* @return A map capable of returning a TemplateNode for a single specified NodeRef reference.
*/
public Map getNodeByReference()
{
return new NodeSearchResultsMap(this, this.services);
}
/** /**
* @return The associations for this Node. As a Map of assoc name to a List of TemplateNodes. * @return The associations for this Node. As a Map of assoc name to a List of TemplateNodes.
*/ */