Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2014 Attila Szegedi, Daniel Dekany, Jonathan Revusky
   * 
   * 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 freemarker.ext.jython;
 
 import java.util.List;
 
 import  org.python.core.Py;
 import  org.python.core.PyDictionary;
 import  org.python.core.PyFloat;
 import  org.python.core.PyInteger;
 import  org.python.core.PyLong;
 import  org.python.core.PyObject;
 import  org.python.core.PySequence;
 import  org.python.core.PyString;
 import  org.python.core.PyStringMap;
 
An object wrapper that wraps Jython objects into FreeMarker template models and vice versa.
 
 public class JythonWrapper implements ObjectWrapper
 {
     private static final Class PYOBJECT_CLASS = PyObject.class;
     public static final JythonWrapper INSTANCE = new JythonWrapper();
 
     private final ModelCache modelCache = new JythonModelCache(this);
 
     private boolean attributesShadowItems = true;
 
     public JythonWrapper()
     {
     }
    
    
Sets whether this wrapper caches model instances. Default is false. When set to true, calling wrap(Object) multiple times for the same object will return the same model.
 
     public void setUseCache(boolean useCache)
     {
         .setUseCache(useCache);
     }
    
    
Sets whether attributes shadow items in wrapped objects. When true (this is the default value), ${object.name} will first try to locate a python attribute with the specified name on the object using PyObject.__findattr__(java.lang.String), and only if it doesn't find the attribute will it call PyObject.__getitem__(org.python.core.PyObject). When set to false, the lookup order is reversed and items are looked up before attributes.
 
     public synchronized void setAttributesShadowItems(boolean attributesShadowItems)
     {
         this. = attributesShadowItems;
     }
     
     boolean isAttributesShadowItems()
     {
         return ;
     }
    
    
Wraps the passed Jython object into a FreeMarker template model. If the object is not a Jython object, it's first coerced into one using Py.java2py(java.lang.Object). PyDictionary and PyStringMap are wrapped into a hash model, PySequence descendants are wrapped into a sequence model, PyInteger, PyLong, and PyFloat are wrapped into a number model. All objects are wrapped into a scalar model (using Object.toString() and a boolean model (using PyObject.__nonzero__(). For internal general-purpose PyObjects returned from a call to unwrap(TemplateModel), the template model that was passed to unwrap is returned.
    public TemplateModel wrap(Object obj)
    {
        if(obj == null) {
            return null;
        }
        return .getInstance(obj);
    }
    
    
Coerces a template model into a PyObject.

Parameters:
model the model to coerce
Returns:
the coerced model.
  • AdapterTemplateModels (i.e. freemarker.ext.beans.BeanModel) are marshalled using the standard Python marshaller Py.java2py(Object) on the result of getWrappedObject(PyObject.class)s. The native JythonModel instances will just return the underlying PyObject.
  • All other models that are scalars are marshalled as PyString.
  • All other models that are numbers are marshalled using the standard Python marshaller Py.java2py(Object) on their underlying Number
  • All other models are marshalled to a generic internal PyObject subclass that'll correctly pass __finditem__, __len__, __nonzero__, and __call__ invocations to appropriate hash, sequence, and method models.
    public PyObject unwrap(TemplateModel modelthrows TemplateModelException
    {
        if(model instanceof AdapterTemplateModel) {
            return Py.java2py(((AdapterTemplateModel)model).getAdaptedObject(
                    ));
        }
        if(model instanceof WrapperTemplateModel) {
            return Py.java2py(((WrapperTemplateModel)model).getWrappedObject());
        }
        // Scalars are marshalled to PyString.
        if(model instanceof TemplateScalarModel)
        {
            return new PyString(((TemplateScalarModel)model).getAsString());
        }
        
        // Numbers are wrapped to Python built-in numeric types.
        if(model instanceof TemplateNumberModel)
        {
            Number number = ((TemplateNumberModel)model).getAsNumber();
            if(number instanceof BigDecimal)
            {
                number = OptimizerUtil.optimizeNumberRepresentation(number);
            }
            if(number instanceof BigInteger)
            {
                // Py.java2py can't automatically coerce a BigInteger into
                // a PyLong. This will probably get fixed in later Jython
                // release.
                return new PyLong((BigInteger)number);
            }
            else
            {
                return Py.java2py(number);
            }
        }
        // Return generic TemplateModel-to-Python adapter
        return new TemplateModelToJythonAdapter(model);
    }
    private class TemplateModelToJythonAdapter extends PyObject 
    implements TemplateModelAdapter 
    {
        private final TemplateModel model;
        
        {
            this. = model;
        }
        
        public TemplateModel getTemplateModel()
        {
            return ;
        }
        
        public PyObject __finditem__(PyObject key)
        {
            if(key instanceof PyInteger)
            {
                return __finditem__(((PyInteger)key).getValue());
            }
            return __finditem__(key.toString());
        }
        public PyObject __finditem__(String key)
        {
            if( instanceof TemplateHashModel)
            {
                try
                {
                    return unwrap(((TemplateHashModel)).get(key));
                }
                catch(TemplateModelException e)
                {
                    throw Py.JavaError(e);
                }
            }
            throw Py.TypeError("item lookup on non-hash model (" + getModelClass() + ")");
        }
        
        public PyObject __finditem__(int index)
        {
            if( instanceof TemplateSequenceModel)
            {
                try
                {
                    return unwrap(((TemplateSequenceModel)).get(index));
                }
                catch(TemplateModelException e)
                {
                    throw Py.JavaError(e);
                }
            }
            throw Py.TypeError("item lookup on non-sequence model (" + getModelClass() + ")");
        }
        
        public PyObject __call__(PyObject args[], String keywords[])
        {
            if( instanceof TemplateMethodModel)
            {
                boolean isEx =  instanceof TemplateMethodModelEx;
                List list = new ArrayList(args.length);
                try
                {
                    for(int i = 0; i < args.length; ++i)
                    {
                        list.add(
                            isEx 
                            ? (Object)wrap(args[i]) 
                            : (Object)(
                                args[i] == null 
                                ? null 
                                : args[i].toString()));
                    }
                    return unwrap((TemplateModel) ((TemplateMethodModelEx)).exec(list));
                }
                catch(TemplateModelException e)
                {
                    throw Py.JavaError(e);
                }
            }
            throw Py.TypeError("call of non-method model (" + getModelClass() + ")");
        }
        
        public int __len__()
        {
            try
            {
                if( instanceof TemplateSequenceModel)
                {
                    return ((TemplateSequenceModel)).size();
                }
                if( instanceof TemplateHashModelEx)
                {
                    return ((TemplateHashModelEx)).size();
                }
            }
            catch(TemplateModelException e)
            {
                throw Py.JavaError(e);
            }
            
            return 0;
        }
        
        public boolean __nonzero__()
        {
            try
            {
                if( instanceof TemplateBooleanModel)
                {
                    return ((TemplateBooleanModel)).getAsBoolean();
                }
                if( instanceof TemplateSequenceModel)
                {
                    return ((TemplateSequenceModel)).size() > 0;
                }
                if( instanceof TemplateHashModel)
                {
                    return !((TemplateHashModelEx)).isEmpty();
                }
            }
            catch(TemplateModelException e)
            {
                throw Py.JavaError(e);
            }
            return false;
        }
        
        private String getModelClass()
        {
            return  == null ? "null" : .getClass().getName();
        }
    }
New to GrepCode? Check out our FAQ X