http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/051a0822/src/main/java/org/apache/freemarker/core/model/impl/beans/EnumerationModel.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/model/impl/beans/EnumerationModel.java b/src/main/java/org/apache/freemarker/core/model/impl/beans/EnumerationModel.java deleted file mode 100644 index e90aab9..0000000 --- a/src/main/java/org/apache/freemarker/core/model/impl/beans/EnumerationModel.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.freemarker.core.model.impl.beans; - -import java.util.Enumeration; -import java.util.NoSuchElementException; - -import org.apache.freemarker.core.model.TemplateCollectionModel; -import org.apache.freemarker.core.model.TemplateModel; -import org.apache.freemarker.core.model.TemplateModelException; -import org.apache.freemarker.core.model.TemplateModelIterator; - -/** - * <p>A class that adds {@link TemplateModelIterator} functionality to the - * {@link Enumeration} interface implementers. - * </p> <p>Using the model as a collection model is NOT thread-safe, as - * enumerations are inherently not thread-safe. - * Further, you can iterate over it only once. Attempts to call the - * {@link #iterator()} method after it was already driven to the end once will - * throw an exception.</p> - */ - -public class EnumerationModel -extends - BeanModel -implements - TemplateModelIterator, - TemplateCollectionModel { - private boolean accessed = false; - - /** - * Creates a new model that wraps the specified enumeration object. - * @param enumeration the enumeration object to wrap into a model. - * @param wrapper the {@link BeansWrapper} associated with this model. - * Every model has to have an associated {@link BeansWrapper} instance. The - * model gains many attributes from its wrapper, including the caching - * behavior, method exposure level, method-over-item shadowing policy etc. - */ - public EnumerationModel(Enumeration enumeration, BeansWrapper wrapper) { - super(enumeration, wrapper); - } - - /** - * This allows the enumeration to be used in a <tt><#list></tt> block. - * @return "this" - */ - @Override - public TemplateModelIterator iterator() throws TemplateModelException { - synchronized (this) { - if (accessed) { - throw new TemplateModelException( - "This collection is stateful and can not be iterated over the" + - " second time."); - } - accessed = true; - } - return this; - } - - /** - * Calls underlying {@link Enumeration#nextElement()}. - */ - @Override - public boolean hasNext() { - return ((Enumeration) object).hasMoreElements(); - } - - - /** - * Calls underlying {@link Enumeration#nextElement()} and wraps the result. - */ - @Override - public TemplateModel next() - throws TemplateModelException { - try { - return wrap(((Enumeration) object).nextElement()); - } catch (NoSuchElementException e) { - throw new TemplateModelException( - "No more elements in the enumeration."); - } - } - - /** - * Returns {@link Enumeration#hasMoreElements()}. Therefore, an - * enumeration that has no more element evaluates to false, and an - * enumeration that has further elements evaluates to true. - */ - public boolean getAsBoolean() { - return hasNext(); - } -}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/051a0822/src/main/java/org/apache/freemarker/core/model/impl/beans/HashAdapter.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/model/impl/beans/HashAdapter.java b/src/main/java/org/apache/freemarker/core/model/impl/beans/HashAdapter.java deleted file mode 100644 index 0fcc58f..0000000 --- a/src/main/java/org/apache/freemarker/core/model/impl/beans/HashAdapter.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.freemarker.core.model.impl.beans; - -import java.util.AbstractMap; -import java.util.AbstractSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; - -import org.apache.freemarker.core.model.TemplateHashModel; -import org.apache.freemarker.core.model.TemplateHashModelEx; -import org.apache.freemarker.core.model.TemplateModel; -import org.apache.freemarker.core.model.TemplateModelAdapter; -import org.apache.freemarker.core.model.TemplateModelException; -import org.apache.freemarker.core.model.TemplateModelIterator; -import org.apache.freemarker.core.util.UndeclaredThrowableException; - -/** - */ -public class HashAdapter extends AbstractMap implements TemplateModelAdapter { - private final BeansWrapper wrapper; - private final TemplateHashModel model; - private Set entrySet; - - HashAdapter(TemplateHashModel model, BeansWrapper wrapper) { - this.model = model; - this.wrapper = wrapper; - } - - @Override - public TemplateModel getTemplateModel() { - return model; - } - - @Override - public boolean isEmpty() { - try { - return model.isEmpty(); - } catch (TemplateModelException e) { - throw new UndeclaredThrowableException(e); - } - } - - @Override - public Object get(Object key) { - try { - return wrapper.unwrap(model.get(String.valueOf(key))); - } catch (TemplateModelException e) { - throw new UndeclaredThrowableException(e); - } - } - - @Override - public boolean containsKey(Object key) { - // A quick check that doesn't require TemplateHashModelEx - if (get(key) != null) { - return true; - } - return super.containsKey(key); - } - - @Override - public Set entrySet() { - if (entrySet != null) { - return entrySet; - } - return entrySet = new AbstractSet() { - @Override - public Iterator iterator() { - final TemplateModelIterator i; - try { - i = getModelEx().keys().iterator(); - } catch (TemplateModelException e) { - throw new UndeclaredThrowableException(e); - } - return new Iterator() { - @Override - public boolean hasNext() { - try { - return i.hasNext(); - } catch (TemplateModelException e) { - throw new UndeclaredThrowableException(e); - } - } - - @Override - public Object next() { - final Object key; - try { - key = wrapper.unwrap(i.next()); - } catch (TemplateModelException e) { - throw new UndeclaredThrowableException(e); - } - return new Map.Entry() { - @Override - public Object getKey() { - return key; - } - - @Override - public Object getValue() { - return get(key); - } - - @Override - public Object setValue(Object value) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof Map.Entry)) - return false; - Map.Entry e = (Map.Entry) o; - Object k1 = getKey(); - Object k2 = e.getKey(); - if (k1 == k2 || (k1 != null && k1.equals(k2))) { - Object v1 = getValue(); - Object v2 = e.getValue(); - if (v1 == v2 || (v1 != null && v1.equals(v2))) - return true; - } - return false; - } - - @Override - public int hashCode() { - Object value = getValue(); - return (key == null ? 0 : key.hashCode()) ^ - (value == null ? 0 : value.hashCode()); - } - }; - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } - - @Override - public int size() { - try { - return getModelEx().size(); - } catch (TemplateModelException e) { - throw new UndeclaredThrowableException(e); - } - } - }; - } - - private TemplateHashModelEx getModelEx() { - if (model instanceof TemplateHashModelEx) { - return ((TemplateHashModelEx) model); - } - throw new UnsupportedOperationException( - "Operation supported only on TemplateHashModelEx. " + - model.getClass().getName() + " does not implement it though."); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/051a0822/src/main/java/org/apache/freemarker/core/model/impl/beans/InvalidPropertyException.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/model/impl/beans/InvalidPropertyException.java b/src/main/java/org/apache/freemarker/core/model/impl/beans/InvalidPropertyException.java deleted file mode 100755 index 5187b15..0000000 --- a/src/main/java/org/apache/freemarker/core/model/impl/beans/InvalidPropertyException.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.freemarker.core.model.impl.beans; - -import org.apache.freemarker.core.model.TemplateModelException; - -/** - * An exception thrown when there is an attempt to access - * an invalid bean property when we are in a "strict bean" mode - */ - -public class InvalidPropertyException extends TemplateModelException { - - public InvalidPropertyException(String description) { - super(description); - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/051a0822/src/main/java/org/apache/freemarker/core/model/impl/beans/IteratorModel.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/model/impl/beans/IteratorModel.java b/src/main/java/org/apache/freemarker/core/model/impl/beans/IteratorModel.java deleted file mode 100644 index 767c15e..0000000 --- a/src/main/java/org/apache/freemarker/core/model/impl/beans/IteratorModel.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.freemarker.core.model.impl.beans; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -import org.apache.freemarker.core.model.TemplateCollectionModel; -import org.apache.freemarker.core.model.TemplateModel; -import org.apache.freemarker.core.model.TemplateModelException; -import org.apache.freemarker.core.model.TemplateModelIterator; - -/** - * <p>A class that adds {@link TemplateModelIterator} functionality to the - * {@link Iterator} interface implementers. - * </p> - * <p>It differs from the {@link org.apache.freemarker.core.model.impl.SimpleCollection} in that - * it inherits from {@link BeanModel}, and therefore you can call methods on - * it directly, even to the effect of calling <tt>iterator.remove()</tt> in - * the template.</p> <p>Using the model as a collection model is NOT - * thread-safe, as iterators are inherently not thread-safe. - * Further, you can iterate over it only once. Attempts to call the - * {@link #iterator()} method after it was already driven to the end once will - * throw an exception.</p> - */ - -public class IteratorModel -extends - BeanModel -implements - TemplateModelIterator, - TemplateCollectionModel { - private boolean accessed = false; - - /** - * Creates a new model that wraps the specified iterator object. - * @param iterator the iterator object to wrap into a model. - * @param wrapper the {@link BeansWrapper} associated with this model. - * Every model has to have an associated {@link BeansWrapper} instance. The - * model gains many attributes from its wrapper, including the caching - * behavior, method exposure level, method-over-item shadowing policy etc. - */ - public IteratorModel(Iterator iterator, BeansWrapper wrapper) { - super(iterator, wrapper); - } - - /** - * This allows the iterator to be used in a <tt><#list></tt> block. - * @return "this" - */ - @Override - public TemplateModelIterator iterator() throws TemplateModelException { - synchronized (this) { - if (accessed) { - throw new TemplateModelException( - "This collection is stateful and can not be iterated over the" + - " second time."); - } - accessed = true; - } - return this; - } - - /** - * Calls underlying {@link Iterator#hasNext()}. - */ - @Override - public boolean hasNext() { - return ((Iterator) object).hasNext(); - } - - - /** - * Calls underlying {@link Iterator#next()} and wraps the result. - */ - @Override - public TemplateModel next() - throws TemplateModelException { - try { - return wrap(((Iterator) object).next()); - } catch (NoSuchElementException e) { - throw new TemplateModelException( - "No more elements in the iterator.", e); - } - } - - /** - * Returns {@link Iterator#hasNext()}. Therefore, an - * iterator that has no more element evaluates to false, and an - * iterator that has further elements evaluates to true. - */ - public boolean getAsBoolean() { - return hasNext(); - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/051a0822/src/main/java/org/apache/freemarker/core/model/impl/beans/JRebelClassChangeNotifier.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/model/impl/beans/JRebelClassChangeNotifier.java b/src/main/java/org/apache/freemarker/core/model/impl/beans/JRebelClassChangeNotifier.java deleted file mode 100644 index 956a6c4..0000000 --- a/src/main/java/org/apache/freemarker/core/model/impl/beans/JRebelClassChangeNotifier.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.freemarker.core.model.impl.beans; - -import java.lang.ref.WeakReference; - -import org.zeroturnaround.javarebel.ClassEventListener; -import org.zeroturnaround.javarebel.ReloaderFactory; - -class JRebelClassChangeNotifier implements ClassChangeNotifier { - - static void testAvailability() { - ReloaderFactory.getInstance(); - } - - @Override - public void subscribe(ClassIntrospector classIntrospector) { - ReloaderFactory.getInstance().addClassReloadListener( - new ClassIntrospectorCacheInvalidator(classIntrospector)); - } - - private static class ClassIntrospectorCacheInvalidator - implements ClassEventListener { - private final WeakReference ref; - - ClassIntrospectorCacheInvalidator(ClassIntrospector w) { - ref = new WeakReference(w); - } - - @Override - public void onClassEvent(int eventType, Class pClass) { - ClassIntrospector ci = (ClassIntrospector) ref.get(); - if (ci == null) { - ReloaderFactory.getInstance().removeClassReloadListener(this); - } else if (eventType == ClassEventListener.EVENT_RELOADED) { - ci.remove(pClass); - } - } - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/051a0822/src/main/java/org/apache/freemarker/core/model/impl/beans/MapModel.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/model/impl/beans/MapModel.java b/src/main/java/org/apache/freemarker/core/model/impl/beans/MapModel.java deleted file mode 100644 index 0af8749..0000000 --- a/src/main/java/org/apache/freemarker/core/model/impl/beans/MapModel.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.freemarker.core.model.impl.beans; - -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.freemarker.core.model.ObjectWrapper; -import org.apache.freemarker.core.model.TemplateMethodModelEx; -import org.apache.freemarker.core.model.TemplateModel; -import org.apache.freemarker.core.model.TemplateModelException; - -/** - * <p>A special case of {@link BeanModel} that adds implementation - * for {@link TemplateMethodModelEx} on map objects that is a shortcut for the - * <tt>Map.get()</tt> method. Note that if the passed argument itself is a - * reflection-wrapper model, then the map lookup will be performed using the - * wrapped object as the key. Note that you can call <tt>get()</tt> using the - * <tt>map.key</tt> syntax inherited from {@link BeanModel} as well, - * however in that case the key is always a string.</p> - * <p>The class itself does not implement the {@link org.apache.freemarker.core.model.TemplateCollectionModel}. - * You can, however use <tt>map.entrySet()</tt>, <tt>map.keySet()</tt>, or - * <tt>map.values()</tt> to obtain {@link org.apache.freemarker.core.model.TemplateCollectionModel} instances for - * various aspects of the map.</p> - */ -public class MapModel -extends - StringModel -implements - TemplateMethodModelEx { - static final ModelFactory FACTORY = - new ModelFactory() - { - @Override - public TemplateModel create(Object object, ObjectWrapper wrapper) { - return new MapModel((Map) object, (BeansWrapper) wrapper); - } - }; - - /** - * Creates a new model that wraps the specified map object. - * @param map the map object to wrap into a model. - * @param wrapper the {@link BeansWrapper} associated with this model. - * Every model has to have an associated {@link BeansWrapper} instance. The - * model gains many attributes from its wrapper, including the caching - * behavior, method exposure level, method-over-item shadowing policy etc. - */ - public MapModel(Map map, BeansWrapper wrapper) { - super(map, wrapper); - } - - /** - * The first argument is used as a key to call the map's <tt>get</tt> method. - */ - @Override - public Object exec(List arguments) - throws TemplateModelException { - Object key = unwrap((TemplateModel) arguments.get(0)); - return wrap(((Map) object).get(key)); - } - - /** - * Overridden to invoke the generic get method by casting to Map instead of - * through reflection - should yield better performance. - */ - @Override - protected TemplateModel invokeGenericGet(Map keyMap, Class clazz, String key) - throws TemplateModelException { - Map map = (Map) object; - Object val = map.get(key); - if (val == null) { - if (key.length() == 1) { - // just check for Character key if this is a single-character string - Character charKey = Character.valueOf(key.charAt(0)); - val = map.get(charKey); - if (val == null && !(map.containsKey(key) || map.containsKey(charKey))) { - return UNKNOWN; - } - } else if (!map.containsKey(key)) { - return UNKNOWN; - } - } - return wrap(val); - } - - @Override - public boolean isEmpty() { - return ((Map) object).isEmpty() && super.isEmpty(); - } - - @Override - public int size() { - return keySet().size(); - } - - @Override - protected Set keySet() { - Set set = super.keySet(); - set.addAll(((Map) object).keySet()); - return set; - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/051a0822/src/main/java/org/apache/freemarker/core/model/impl/beans/MaybeEmptyCallableMemberDescriptor.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/model/impl/beans/MaybeEmptyCallableMemberDescriptor.java b/src/main/java/org/apache/freemarker/core/model/impl/beans/MaybeEmptyCallableMemberDescriptor.java deleted file mode 100644 index 03791ab..0000000 --- a/src/main/java/org/apache/freemarker/core/model/impl/beans/MaybeEmptyCallableMemberDescriptor.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.freemarker.core.model.impl.beans; - -/** - * Superclass of the {@link EmptyCallableMemberDescriptor} and {@link CallableMemberDescriptor} "case classes". - */ -abstract class MaybeEmptyCallableMemberDescriptor { } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/051a0822/src/main/java/org/apache/freemarker/core/model/impl/beans/MaybeEmptyMemberAndArguments.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/model/impl/beans/MaybeEmptyMemberAndArguments.java b/src/main/java/org/apache/freemarker/core/model/impl/beans/MaybeEmptyMemberAndArguments.java deleted file mode 100644 index c278243..0000000 --- a/src/main/java/org/apache/freemarker/core/model/impl/beans/MaybeEmptyMemberAndArguments.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.freemarker.core.model.impl.beans; - -abstract class MaybeEmptyMemberAndArguments { } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/051a0822/src/main/java/org/apache/freemarker/core/model/impl/beans/MemberAndArguments.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/model/impl/beans/MemberAndArguments.java b/src/main/java/org/apache/freemarker/core/model/impl/beans/MemberAndArguments.java deleted file mode 100644 index b22a63e..0000000 --- a/src/main/java/org/apache/freemarker/core/model/impl/beans/MemberAndArguments.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.freemarker.core.model.impl.beans; - -import java.lang.reflect.InvocationTargetException; - -import org.apache.freemarker.core.model.TemplateModel; -import org.apache.freemarker.core.model.TemplateModelException; - -/** - */ -class MemberAndArguments extends MaybeEmptyMemberAndArguments { - - private final CallableMemberDescriptor callableMemberDesc; - private final Object[] args; - - /** - * @param args The already unwrapped arguments - */ - MemberAndArguments(CallableMemberDescriptor callableMemberDesc, Object[] args) { - this.callableMemberDesc = callableMemberDesc; - this.args = args; - } - - /** - * The already unwrapped arguments. - */ - Object[] getArgs() { - return args; - } - - TemplateModel invokeMethod(BeansWrapper bw, Object obj) - throws TemplateModelException, InvocationTargetException, IllegalAccessException { - return callableMemberDesc.invokeMethod(bw, obj, args); - } - - Object invokeConstructor(BeansWrapper bw) - throws IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException, - TemplateModelException { - return callableMemberDesc.invokeConstructor(bw, args); - } - - CallableMemberDescriptor getCallableMemberDescriptor() { - return callableMemberDesc; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/051a0822/src/main/java/org/apache/freemarker/core/model/impl/beans/MethodAppearanceFineTuner.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/model/impl/beans/MethodAppearanceFineTuner.java b/src/main/java/org/apache/freemarker/core/model/impl/beans/MethodAppearanceFineTuner.java deleted file mode 100644 index ea72fb2..0000000 --- a/src/main/java/org/apache/freemarker/core/model/impl/beans/MethodAppearanceFineTuner.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.freemarker.core.model.impl.beans; - -import java.beans.IndexedPropertyDescriptor; -import java.beans.PropertyDescriptor; - -import org.apache.freemarker.core.model.impl.beans.BeansWrapper.MethodAppearanceDecision; -import org.apache.freemarker.core.model.impl.beans.BeansWrapper.MethodAppearanceDecisionInput; - -/** - * Used for customizing how the methods are visible from templates, via - * {@link BeansWrapper#setMethodAppearanceFineTuner(MethodAppearanceFineTuner)}. - * The object that implements this should also implement {@link SingletonCustomizer} whenever possible. - * - * @since 2.3.21 - */ -public interface MethodAppearanceFineTuner { - - /** - * Implement this to tweak certain aspects of how methods appear in the - * data-model. {@link BeansWrapper} will pass in all Java methods here that - * it intends to expose in the data-model as methods (so you can do - * <tt>obj.foo()</tt> in the template). - * With this method you can do the following tweaks: - * <ul> - * <li>Hide a method that would be otherwise shown by calling - * {@link MethodAppearanceDecision#setExposeMethodAs(String)} - * with <tt>null</tt> parameter. Note that you can't un-hide methods - * that are not public or are considered to by unsafe - * (like {@link Object#wait()}) because - * {@link #process} is not called for those.</li> - * <li>Show the method with a different name in the data-model than its - * real name by calling - * {@link MethodAppearanceDecision#setExposeMethodAs(String)} - * with non-<tt>null</tt> parameter. - * <li>Create a fake JavaBean property for this method by calling - * {@link MethodAppearanceDecision#setExposeAsProperty(PropertyDescriptor)}. - * For example, if you have <tt>int size()</tt> in a class, but you - * want it to be accessed from the templates as <tt>obj.size</tt>, - * rather than as <tt>obj.size()</tt>, you can do that with this. - * The default is {@code null}, which means that no fake property is - * created for the method. You need not and shouldn't set this - * to non-<tt>null</tt> for the getter methods of real JavaBean - * properties, as those are automatically shown as properties anyway. - * The property name in the {@link PropertyDescriptor} can be anything, - * but the method (or methods) in it must belong to the class that - * is given as the <tt>clazz</tt> parameter or it must be inherited from - * that class, or else whatever errors can occur later. - * {@link IndexedPropertyDescriptor}-s are supported. - * If a real JavaBean property of the same name exists, it won't be - * replaced by the fake one. Also if a fake property of the same name - * was assigned earlier, it won't be replaced. - * <li>Prevent the method to hide a JavaBean property (fake or real) of - * the same name by calling - * {@link MethodAppearanceDecision#setMethodShadowsProperty(boolean)} - * with <tt>false</tt>. The default is <tt>true</tt>, so if you have - * both a property and a method called "foo", then in the template - * <tt>myObject.foo</tt> will return the method itself instead - * of the property value, which is often undesirable. - * </ul> - * - * <p>Note that you can expose a Java method both as a method and as a - * JavaBean property on the same time, however you have to chose different - * names for them to prevent shadowing. - * - * @param in Describes the method about which the decision will have to be made. - * - * @param out Stores how the method will be exposed in the - * data-model after {@link #process} returns. - * This is initialized so that it reflects the default - * behavior of {@link BeansWrapper}, so you don't have to do anything with this - * when you don't want to change the default behavior. - */ - void process(MethodAppearanceDecisionInput in, MethodAppearanceDecision out); - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/051a0822/src/main/java/org/apache/freemarker/core/model/impl/beans/MethodSorter.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/model/impl/beans/MethodSorter.java b/src/main/java/org/apache/freemarker/core/model/impl/beans/MethodSorter.java deleted file mode 100644 index d812910..0000000 --- a/src/main/java/org/apache/freemarker/core/model/impl/beans/MethodSorter.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.freemarker.core.model.impl.beans; - -import java.beans.MethodDescriptor; - -/** - * Used for JUnit testing method-order dependence bugs via - * {@link BeansWrapperBuilder#setMethodSorter(MethodSorter)}. - */ -interface MethodSorter { - - MethodDescriptor[] sortMethodDescriptors(MethodDescriptor[] methodDescriptors); - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/051a0822/src/main/java/org/apache/freemarker/core/model/impl/beans/ModelCache.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/model/impl/beans/ModelCache.java b/src/main/java/org/apache/freemarker/core/model/impl/beans/ModelCache.java deleted file mode 100644 index 4c5e415..0000000 --- a/src/main/java/org/apache/freemarker/core/model/impl/beans/ModelCache.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.freemarker.core.model.impl.beans; - -import java.lang.ref.ReferenceQueue; -import java.lang.ref.SoftReference; -import java.util.IdentityHashMap; -import java.util.Map; - -import org.apache.freemarker.core.model.TemplateModel; -import org.apache.freemarker.core.model.TemplateModelAdapter; - -/** - * Internally used by various wrapper implementations to implement model - * caching. - */ -public abstract class ModelCache { - private boolean useCache = false; - private Map<Object, ModelReference> modelCache = null; - private ReferenceQueue<TemplateModel> refQueue = null; - - protected ModelCache() { - } - - /** - * Sets whether this wrapper caches model instances. Default is false. - * When set to true, calling {@link #getInstance(Object)} - * multiple times for the same object will return the same model. - */ - public synchronized void setUseCache(boolean useCache) { - this.useCache = useCache; - if (useCache) { - modelCache = new IdentityHashMap<>(); - refQueue = new ReferenceQueue<>(); - } else { - modelCache = null; - refQueue = null; - } - } - - /** - * @since 2.3.21 - */ - public synchronized boolean getUseCache() { - return useCache; - } - - public TemplateModel getInstance(Object object) { - if (object instanceof TemplateModel) { - return (TemplateModel) object; - } - if (object instanceof TemplateModelAdapter) { - return ((TemplateModelAdapter) object).getTemplateModel(); - } - if (useCache && isCacheable(object)) { - TemplateModel model = lookup(object); - if (model == null) { - model = create(object); - register(model, object); - } - return model; - } else { - return create(object); - } - } - - protected abstract TemplateModel create(Object object); - protected abstract boolean isCacheable(Object object); - - public void clearCache() { - if (modelCache != null) { - synchronized (modelCache) { - modelCache.clear(); - } - } - } - - private TemplateModel lookup(Object object) { - ModelReference ref = null; - // NOTE: we're doing minimal synchronizations -- which can lead to - // duplicate wrapper creation. However, this has no harmful side-effects and - // is a lesser performance hit. - synchronized (modelCache) { - ref = modelCache.get(object); - } - - if (ref != null) - return ref.getModel(); - - return null; - } - - private void register(TemplateModel model, Object object) { - synchronized (modelCache) { - // Remove cleared references - for (; ; ) { - ModelReference queuedRef = (ModelReference) refQueue.poll(); - if (queuedRef == null) { - break; - } - modelCache.remove(queuedRef.object); - } - // Register new reference - modelCache.put(object, new ModelReference(model, object, refQueue)); - } - } - - /** - * A special soft reference that is registered in the modelCache. - * When it gets cleared (that is, the model became unreachable) - * it will remove itself from the model cache. - */ - private static final class ModelReference extends SoftReference<TemplateModel> { - Object object; - - ModelReference(TemplateModel ref, Object object, ReferenceQueue<TemplateModel> refQueue) { - super(ref, refQueue); - this.object = object; - } - - TemplateModel getModel() { - return get(); - } - } - -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/051a0822/src/main/java/org/apache/freemarker/core/model/impl/beans/ModelFactory.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/model/impl/beans/ModelFactory.java b/src/main/java/org/apache/freemarker/core/model/impl/beans/ModelFactory.java deleted file mode 100644 index a09d31b..0000000 --- a/src/main/java/org/apache/freemarker/core/model/impl/beans/ModelFactory.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.freemarker.core.model.impl.beans; - -import org.apache.freemarker.core.model.ObjectWrapper; -import org.apache.freemarker.core.model.TemplateModel; - -/** - * Interface used to create various wrapper models in the {@link ModelCache}. - */ -public interface ModelFactory { - /** - * Create a wrapping model for the specified object that belongs to - * the specified wrapper. - */ - TemplateModel create(Object object, ObjectWrapper wrapper); -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/051a0822/src/main/java/org/apache/freemarker/core/model/impl/beans/NonPrimitiveArrayBackedReadOnlyList.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/model/impl/beans/NonPrimitiveArrayBackedReadOnlyList.java b/src/main/java/org/apache/freemarker/core/model/impl/beans/NonPrimitiveArrayBackedReadOnlyList.java deleted file mode 100644 index f2fc97d..0000000 --- a/src/main/java/org/apache/freemarker/core/model/impl/beans/NonPrimitiveArrayBackedReadOnlyList.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.freemarker.core.model.impl.beans; - -import java.util.AbstractList; - -class NonPrimitiveArrayBackedReadOnlyList extends AbstractList { - - private final Object[] array; - - NonPrimitiveArrayBackedReadOnlyList(Object[] array) { - this.array = array; - } - - @Override - public Object get(int index) { - return array[index]; - } - - @Override - public int size() { - return array.length; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/051a0822/src/main/java/org/apache/freemarker/core/model/impl/beans/NumberModel.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/model/impl/beans/NumberModel.java b/src/main/java/org/apache/freemarker/core/model/impl/beans/NumberModel.java deleted file mode 100644 index 1d0013e..0000000 --- a/src/main/java/org/apache/freemarker/core/model/impl/beans/NumberModel.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.freemarker.core.model.impl.beans; - -import org.apache.freemarker.core.model.ObjectWrapper; -import org.apache.freemarker.core.model.TemplateModel; -import org.apache.freemarker.core.model.TemplateNumberModel; - -/** - * Wraps arbitrary subclass of {@link java.lang.Number} into a reflective model. - * Beside acting as a {@link TemplateNumberModel}, you can call all Java methods on - * these objects as well. - */ -public class NumberModel -extends - BeanModel -implements - TemplateNumberModel { - static final ModelFactory FACTORY = - new ModelFactory() - { - @Override - public TemplateModel create(Object object, ObjectWrapper wrapper) { - return new NumberModel((Number) object, (BeansWrapper) wrapper); - } - }; - /** - * Creates a new model that wraps the specified number object. - * @param number the number object to wrap into a model. - * @param wrapper the {@link BeansWrapper} associated with this model. - * Every model has to have an associated {@link BeansWrapper} instance. The - * model gains many attributes from its wrapper, including the caching - * behavior, method exposure level, method-over-item shadowing policy etc. - */ - public NumberModel(Number number, BeansWrapper wrapper) { - super(number, wrapper); - } - - @Override - public Number getAsNumber() { - return (Number) object; - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/051a0822/src/main/java/org/apache/freemarker/core/model/impl/beans/OverloadedFixArgsMethods.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/model/impl/beans/OverloadedFixArgsMethods.java b/src/main/java/org/apache/freemarker/core/model/impl/beans/OverloadedFixArgsMethods.java deleted file mode 100644 index a1de28b..0000000 --- a/src/main/java/org/apache/freemarker/core/model/impl/beans/OverloadedFixArgsMethods.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.freemarker.core.model.impl.beans; - -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import org.apache.freemarker.core.model.ObjectWrapperAndUnwrapper; -import org.apache.freemarker.core.model.TemplateModel; -import org.apache.freemarker.core.model.TemplateModelException; - -/** - * Stores the non-varargs methods for a {@link OverloadedMethods} object. - */ -class OverloadedFixArgsMethods extends OverloadedMethodsSubset { - - OverloadedFixArgsMethods() { - super(); - } - - @Override - Class[] preprocessParameterTypes(CallableMemberDescriptor memberDesc) { - return memberDesc.getParamTypes(); - } - - @Override - void afterWideningUnwrappingHints(Class[] paramTypes, int[] paramNumericalTypes) { - // Do nothing - } - - @Override - MaybeEmptyMemberAndArguments getMemberAndArguments(List tmArgs, BeansWrapper unwrapper) - throws TemplateModelException { - if (tmArgs == null) { - // null is treated as empty args - tmArgs = Collections.EMPTY_LIST; - } - final int argCount = tmArgs.size(); - final Class[][] unwrappingHintsByParamCount = getUnwrappingHintsByParamCount(); - if (unwrappingHintsByParamCount.length <= argCount) { - return EmptyMemberAndArguments.WRONG_NUMBER_OF_ARGUMENTS; - } - Class[] unwarppingHints = unwrappingHintsByParamCount[argCount]; - if (unwarppingHints == null) { - return EmptyMemberAndArguments.WRONG_NUMBER_OF_ARGUMENTS; - } - - Object[] pojoArgs = new Object[argCount]; - - int[] typeFlags = getTypeFlags(argCount); - if (typeFlags == ALL_ZEROS_ARRAY) { - typeFlags = null; - } - - Iterator it = tmArgs.iterator(); - for (int i = 0; i < argCount; ++i) { - Object pojo = unwrapper.tryUnwrapTo( - (TemplateModel) it.next(), - unwarppingHints[i], - typeFlags != null ? typeFlags[i] : 0); - if (pojo == ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS) { - return EmptyMemberAndArguments.noCompatibleOverload(i + 1); - } - pojoArgs[i] = pojo; - } - - MaybeEmptyCallableMemberDescriptor maybeEmtpyMemberDesc = getMemberDescriptorForArgs(pojoArgs, false); - if (maybeEmtpyMemberDesc instanceof CallableMemberDescriptor) { - CallableMemberDescriptor memberDesc = (CallableMemberDescriptor) maybeEmtpyMemberDesc; - if (typeFlags != null) { - // Note that overloaded method selection has already accounted for overflow errors when the method - // was selected. So this forced conversion shouldn't cause such corruption. Except, conversion from - // BigDecimal is allowed to overflow for backward-compatibility. - forceNumberArgumentsToParameterTypes(pojoArgs, memberDesc.getParamTypes(), typeFlags); - } - return new MemberAndArguments(memberDesc, pojoArgs); - } else { - return EmptyMemberAndArguments.from((EmptyCallableMemberDescriptor) maybeEmtpyMemberDesc, pojoArgs); - } - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/051a0822/src/main/java/org/apache/freemarker/core/model/impl/beans/OverloadedMethods.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/model/impl/beans/OverloadedMethods.java b/src/main/java/org/apache/freemarker/core/model/impl/beans/OverloadedMethods.java deleted file mode 100644 index f53596b..0000000 --- a/src/main/java/org/apache/freemarker/core/model/impl/beans/OverloadedMethods.java +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.freemarker.core.model.impl.beans; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; - -import org.apache.freemarker.core._DelayedConversionToString; -import org.apache.freemarker.core._ErrorDescriptionBuilder; -import org.apache.freemarker.core._TemplateModelException; -import org.apache.freemarker.core.model.TemplateMarkupOutputModel; -import org.apache.freemarker.core.model.TemplateModel; -import org.apache.freemarker.core.model.TemplateModelException; -import org.apache.freemarker.core.util.FTLUtil; -import org.apache.freemarker.core.util._ClassUtil; - -/** - * Used instead of {@link java.lang.reflect.Method} or {@link java.lang.reflect.Constructor} for overloaded methods and - * constructors. - * - * <p>After the initialization with the {@link #addMethod(Method)} and {@link #addConstructor(Constructor)} calls are - * done, the instance must be thread-safe. Before that, it's the responsibility of the caller of those methods to - * ensure that the object is properly publishing to other threads. - */ -final class OverloadedMethods { - - private final OverloadedMethodsSubset fixArgMethods; - private OverloadedMethodsSubset varargMethods; - - OverloadedMethods() { - fixArgMethods = new OverloadedFixArgsMethods(); - } - - void addMethod(Method method) { - final Class[] paramTypes = method.getParameterTypes(); - addCallableMemberDescriptor(new ReflectionCallableMemberDescriptor(method, paramTypes)); - } - - void addConstructor(Constructor constr) { - final Class[] paramTypes = constr.getParameterTypes(); - addCallableMemberDescriptor(new ReflectionCallableMemberDescriptor(constr, paramTypes)); - } - - private void addCallableMemberDescriptor(ReflectionCallableMemberDescriptor memberDesc) { - // Note: "varargs" methods are always callable as oms args, with a sequence (array) as the last parameter. - fixArgMethods.addCallableMemberDescriptor(memberDesc); - if (memberDesc.isVarargs()) { - if (varargMethods == null) { - varargMethods = new OverloadedVarArgsMethods(); - } - varargMethods.addCallableMemberDescriptor(memberDesc); - } - } - - MemberAndArguments getMemberAndArguments(List/*<TemplateModel>*/ tmArgs, BeansWrapper unwrapper) - throws TemplateModelException { - // Try to find a oms args match: - MaybeEmptyMemberAndArguments fixArgsRes = fixArgMethods.getMemberAndArguments(tmArgs, unwrapper); - if (fixArgsRes instanceof MemberAndArguments) { - return (MemberAndArguments) fixArgsRes; - } - - // Try to find a varargs match: - MaybeEmptyMemberAndArguments varargsRes; - if (varargMethods != null) { - varargsRes = varargMethods.getMemberAndArguments(tmArgs, unwrapper); - if (varargsRes instanceof MemberAndArguments) { - return (MemberAndArguments) varargsRes; - } - } else { - varargsRes = null; - } - - _ErrorDescriptionBuilder edb = new _ErrorDescriptionBuilder( - toCompositeErrorMessage( - (EmptyMemberAndArguments) fixArgsRes, - (EmptyMemberAndArguments) varargsRes, - tmArgs), - "\nThe matching overload was searched among these members:\n", - memberListToString()); - addMarkupBITipAfterNoNoMarchIfApplicable(edb, tmArgs); - throw new _TemplateModelException(edb); - } - - private Object[] toCompositeErrorMessage( - final EmptyMemberAndArguments fixArgsEmptyRes, final EmptyMemberAndArguments varargsEmptyRes, - List tmArgs) { - final Object[] argsErrorMsg; - if (varargsEmptyRes != null) { - if (fixArgsEmptyRes == null || fixArgsEmptyRes.isNumberOfArgumentsWrong()) { - argsErrorMsg = toErrorMessage(varargsEmptyRes, tmArgs); - } else { - argsErrorMsg = new Object[] { - "When trying to call the non-varargs overloads:\n", - toErrorMessage(fixArgsEmptyRes, tmArgs), - "\nWhen trying to call the varargs overloads:\n", - toErrorMessage(varargsEmptyRes, null) - }; - } - } else { - argsErrorMsg = toErrorMessage(fixArgsEmptyRes, tmArgs); - } - return argsErrorMsg; - } - - private Object[] toErrorMessage(EmptyMemberAndArguments res, List/*<TemplateModel>*/ tmArgs) { - final Object[] unwrappedArgs = res.getUnwrappedArguments(); - return new Object[] { - res.getErrorDescription(), - tmArgs != null - ? new Object[] { - "\nThe FTL type of the argument values were: ", getTMActualParameterTypes(tmArgs), "." } - : "", - unwrappedArgs != null - ? new Object[] { - "\nThe Java type of the argument values were: ", - getUnwrappedActualParameterTypes(unwrappedArgs) + "." } - : ""}; - } - - private _DelayedConversionToString memberListToString() { - return new _DelayedConversionToString(null) { - - @Override - protected String doConversion(Object obj) { - final Iterator fixArgMethodsIter = fixArgMethods.getMemberDescriptors(); - final Iterator varargMethodsIter = varargMethods != null ? varargMethods.getMemberDescriptors() : null; - - boolean hasMethods = fixArgMethodsIter.hasNext() || (varargMethodsIter != null && varargMethodsIter.hasNext()); - if (hasMethods) { - StringBuilder sb = new StringBuilder(); - HashSet fixArgMethods = new HashSet(); - while (fixArgMethodsIter.hasNext()) { - if (sb.length() != 0) sb.append(",\n"); - sb.append(" "); - CallableMemberDescriptor callableMemberDesc = (CallableMemberDescriptor) fixArgMethodsIter.next(); - fixArgMethods.add(callableMemberDesc); - sb.append(callableMemberDesc.getDeclaration()); - } - if (varargMethodsIter != null) { - while (varargMethodsIter.hasNext()) { - CallableMemberDescriptor callableMemberDesc = (CallableMemberDescriptor) varargMethodsIter.next(); - if (!fixArgMethods.contains(callableMemberDesc)) { - if (sb.length() != 0) sb.append(",\n"); - sb.append(" "); - sb.append(callableMemberDesc.getDeclaration()); - } - } - } - return sb.toString(); - } else { - return "No members"; - } - } - - }; - } - - /** - * Adds tip to the error message if converting a {@link TemplateMarkupOutputModel} argument to {@link String} might - * allows finding a matching overload. - */ - private void addMarkupBITipAfterNoNoMarchIfApplicable(_ErrorDescriptionBuilder edb, - List tmArgs) { - for (int argIdx = 0; argIdx < tmArgs.size(); argIdx++) { - Object tmArg = tmArgs.get(argIdx); - if (tmArg instanceof TemplateMarkupOutputModel) { - for (Iterator membDescs = fixArgMethods.getMemberDescriptors(); membDescs.hasNext();) { - CallableMemberDescriptor membDesc = (CallableMemberDescriptor) membDescs.next(); - Class[] paramTypes = membDesc.getParamTypes(); - - Class paramType = null; - if (membDesc.isVarargs() && argIdx >= paramTypes.length - 1) { - paramType = paramTypes[paramTypes.length - 1]; - if (paramType.isArray()) { - paramType = paramType.getComponentType(); - } - } - if (paramType == null && argIdx < paramTypes.length) { - paramType = paramTypes[argIdx]; - } - if (paramType != null) { - if (paramType.isAssignableFrom(String.class) && !paramType.isAssignableFrom(tmArg.getClass())) { - edb.tip(SimpleMethodModel.MARKUP_OUTPUT_TO_STRING_TIP); - return; - } - } - } - } - } - } - - private _DelayedConversionToString getTMActualParameterTypes(List arguments) { - final String[] argumentTypeDescs = new String[arguments.size()]; - for (int i = 0; i < arguments.size(); i++) { - argumentTypeDescs[i] = FTLUtil.getTypeDescription((TemplateModel) arguments.get(i)); - } - - return new DelayedCallSignatureToString(argumentTypeDescs) { - - @Override - String argumentToString(Object argType) { - return (String) argType; - } - - }; - } - - private Object getUnwrappedActualParameterTypes(Object[] unwrappedArgs) { - final Class[] argumentTypes = new Class[unwrappedArgs.length]; - for (int i = 0; i < unwrappedArgs.length; i++) { - Object unwrappedArg = unwrappedArgs[i]; - argumentTypes[i] = unwrappedArg != null ? unwrappedArg.getClass() : null; - } - - return new DelayedCallSignatureToString(argumentTypes) { - - @Override - String argumentToString(Object argType) { - return argType != null - ? _ClassUtil.getShortClassName((Class) argType) - : _ClassUtil.getShortClassNameOfObject(null); - } - - }; - } - - private abstract class DelayedCallSignatureToString extends _DelayedConversionToString { - - public DelayedCallSignatureToString(Object[] argTypeArray) { - super(argTypeArray); - } - - @Override - protected String doConversion(Object obj) { - Object[] argTypes = (Object[]) obj; - - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < argTypes.length; i++) { - if (i != 0) sb.append(", "); - sb.append(argumentToString(argTypes[i])); - } - - return sb.toString(); - } - - abstract String argumentToString(Object argType); - - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/051a0822/src/main/java/org/apache/freemarker/core/model/impl/beans/OverloadedMethodsModel.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/model/impl/beans/OverloadedMethodsModel.java b/src/main/java/org/apache/freemarker/core/model/impl/beans/OverloadedMethodsModel.java deleted file mode 100644 index 9951c3e..0000000 --- a/src/main/java/org/apache/freemarker/core/model/impl/beans/OverloadedMethodsModel.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.freemarker.core.model.impl.beans; - - -import java.util.Collections; -import java.util.List; - -import org.apache.freemarker.core.model.TemplateMethodModelEx; -import org.apache.freemarker.core.model.TemplateModel; -import org.apache.freemarker.core.model.TemplateModelException; -import org.apache.freemarker.core.model.TemplateSequenceModel; -import org.apache.freemarker.core.model.impl.SimpleNumber; - -/** - * Wraps a set of same-name overloaded methods behind {@link org.apache.freemarker.core.model.TemplateMethodModel} interface, - * like if it was a single method, chooses among them behind the scenes on call-time based on the argument values. - */ -public class OverloadedMethodsModel -implements - TemplateMethodModelEx, - TemplateSequenceModel { - private final Object object; - private final OverloadedMethods overloadedMethods; - private final BeansWrapper wrapper; - - OverloadedMethodsModel(Object object, OverloadedMethods overloadedMethods, BeansWrapper wrapper) { - this.object = object; - this.overloadedMethods = overloadedMethods; - this.wrapper = wrapper; - } - - /** - * Invokes the method, passing it the arguments from the list. The actual - * method to call from several overloaded methods will be chosen based - * on the classes of the arguments. - * @throws TemplateModelException if the method cannot be chosen - * unambiguously. - */ - @Override - public Object exec(List arguments) - throws TemplateModelException { - MemberAndArguments maa = overloadedMethods.getMemberAndArguments(arguments, wrapper); - try { - return maa.invokeMethod(wrapper, object); - } catch (Exception e) { - if (e instanceof TemplateModelException) throw (TemplateModelException) e; - - throw _MethodUtil.newInvocationTemplateModelException( - object, - maa.getCallableMemberDescriptor(), - e); - } - } - - @Override - public TemplateModel get(int index) throws TemplateModelException { - return (TemplateModel) exec(Collections.singletonList( - new SimpleNumber(Integer.valueOf(index)))); - } - - @Override - public int size() throws TemplateModelException { - throw new TemplateModelException("?size is unsupported for " + getClass().getName()); - } -}
