http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/ext/beans/OverloadedVarArgsMethods.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/beans/OverloadedVarArgsMethods.java b/src/main/java/freemarker/ext/beans/OverloadedVarArgsMethods.java deleted file mode 100644 index feda735..0000000 --- a/src/main/java/freemarker/ext/beans/OverloadedVarArgsMethods.java +++ /dev/null @@ -1,251 +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 freemarker.ext.beans; - -import java.lang.reflect.Array; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import freemarker.core.BugException; -import freemarker.template.ObjectWrapperAndUnwrapper; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; - -/** - * Stores the varargs methods for a {@link OverloadedMethods} object. - */ -class OverloadedVarArgsMethods extends OverloadedMethodsSubset { - - OverloadedVarArgsMethods(boolean bugfixed) { - super(bugfixed); - } - - /** - * Replaces the last parameter type with the array component type of it. - */ - @Override - Class[] preprocessParameterTypes(CallableMemberDescriptor memberDesc) { - final Class[] preprocessedParamTypes = memberDesc.getParamTypes().clone(); - int ln = preprocessedParamTypes.length; - final Class varArgsCompType = preprocessedParamTypes[ln - 1].getComponentType(); - if (varArgsCompType == null) { - throw new BugException("Only varargs methods should be handled here"); - } - preprocessedParamTypes[ln - 1] = varArgsCompType; - return preprocessedParamTypes; - } - - @Override - void afterWideningUnwrappingHints(Class[] paramTypes, int[] paramNumericalTypes) { - // Overview - // -------- - // - // So far, m(t1, t2...) was treated by the hint widening like m(t1, t2). So now we have to continue hint - // widening like if we had further methods: - // - m(t1, t2, t2), m(t1, t2, t2, t2), ... - // - m(t1), because a varargs array can be 0 long - // - // But we can't do that for real, because we had to add infinite number of methods. Also, for efficiency we - // don't want to create unwrappingHintsByParamCount entries at the indices which are still unused. - // So we only update the already existing hints. Remember that we already have m(t1, t2) there. - - final int paramCount = paramTypes.length; - final Class[][] unwrappingHintsByParamCount = getUnwrappingHintsByParamCount(); - - // The case of e(t1, t2), e(t1, t2, t2), e(t1, t2, t2, t2), ..., where e is an *earlierly* added method. - // When that was added, this method wasn't added yet, so it had no chance updating the hints of this method, - // so we do that now: - // FIXME: Only needed if m(t1, t2) was filled an empty slot, otherwise whatever was there was already - // widened by the preceding hints, so this will be a no-op. - for (int i = paramCount - 1; i >= 0; i--) { - final Class[] previousHints = unwrappingHintsByParamCount[i]; - if (previousHints != null) { - widenHintsToCommonSupertypes( - paramCount, - previousHints, getTypeFlags(i)); - break; // we only do this for the first hit, as the methods before that has already widened it. - } - } - // The case of e(t1), where e is an *earlier* added method. - // When that was added, this method wasn't added yet, so it had no chance updating the hints of this method, - // so we do that now: - // FIXME: Same as above; it's often unnecessary. - if (paramCount + 1 < unwrappingHintsByParamCount.length) { - Class[] oneLongerHints = unwrappingHintsByParamCount[paramCount + 1]; - if (oneLongerHints != null) { - widenHintsToCommonSupertypes( - paramCount, - oneLongerHints, getTypeFlags(paramCount + 1)); - } - } - - // The case of m(t1, t2, t2), m(t1, t2, t2, t2), ..., where m is the currently added method. - // Update the longer hints-arrays: - for (int i = paramCount + 1; i < unwrappingHintsByParamCount.length; i++) { - widenHintsToCommonSupertypes( - i, - paramTypes, paramNumericalTypes); - } - // The case of m(t1) where m is the currently added method. - // update the one-shorter hints-array: - if (paramCount > 0) { // (should be always true, or else it wasn't a varags method) - widenHintsToCommonSupertypes( - paramCount - 1, - paramTypes, paramNumericalTypes); - } - - } - - private void widenHintsToCommonSupertypes( - int paramCountOfWidened, Class[] wideningTypes, int[] wideningTypeFlags) { - final Class[] typesToWiden = getUnwrappingHintsByParamCount()[paramCountOfWidened]; - if (typesToWiden == null) { - return; // no such overload exists; nothing to widen - } - - final int typesToWidenLen = typesToWiden.length; - final int wideningTypesLen = wideningTypes.length; - int min = Math.min(wideningTypesLen, typesToWidenLen); - for (int i = 0; i < min; ++i) { - typesToWiden[i] = getCommonSupertypeForUnwrappingHint(typesToWiden[i], wideningTypes[i]); - } - if (typesToWidenLen > wideningTypesLen) { - Class varargsComponentType = wideningTypes[wideningTypesLen - 1]; - for (int i = wideningTypesLen; i < typesToWidenLen; ++i) { - typesToWiden[i] = getCommonSupertypeForUnwrappingHint(typesToWiden[i], varargsComponentType); - } - } - - if (bugfixed) { - mergeInTypesFlags(paramCountOfWidened, wideningTypeFlags); - } - } - - @Override - MaybeEmptyMemberAndArguments getMemberAndArguments(List tmArgs, BeansWrapper unwrapper) - throws TemplateModelException { - if (tmArgs == null) { - // null is treated as empty args - tmArgs = Collections.EMPTY_LIST; - } - final int argsLen = tmArgs.size(); - final Class[][] unwrappingHintsByParamCount = getUnwrappingHintsByParamCount(); - final Object[] pojoArgs = new Object[argsLen]; - int[] typesFlags = null; - // Going down starting from methods with args.length + 1 parameters, because we must try to match against a case - // where all specified args are fixargs, and we have 0 varargs. - outer: for (int paramCount = Math.min(argsLen + 1, unwrappingHintsByParamCount.length - 1); paramCount >= 0; --paramCount) { - Class[] unwarappingHints = unwrappingHintsByParamCount[paramCount]; - if (unwarappingHints == null) { - if (paramCount == 0) { - return EmptyMemberAndArguments.WRONG_NUMBER_OF_ARGUMENTS; - } - continue; - } - - typesFlags = getTypeFlags(paramCount); - if (typesFlags == ALL_ZEROS_ARRAY) { - typesFlags = null; - } - - // Try to unwrap the arguments - Iterator it = tmArgs.iterator(); - for (int i = 0; i < argsLen; ++i) { - int paramIdx = i < paramCount ? i : paramCount - 1; - Object pojo = unwrapper.tryUnwrapTo( - (TemplateModel) it.next(), - unwarappingHints[paramIdx], - typesFlags != null ? typesFlags[paramIdx] : 0); - if (pojo == ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS) { - continue outer; - } - pojoArgs[i] = pojo; - } - break outer; - } - - MaybeEmptyCallableMemberDescriptor maybeEmtpyMemberDesc = getMemberDescriptorForArgs(pojoArgs, true); - if (maybeEmtpyMemberDesc instanceof CallableMemberDescriptor) { - CallableMemberDescriptor memberDesc = (CallableMemberDescriptor) maybeEmtpyMemberDesc; - Object[] pojoArgsWithArray; - Object argsOrErrorIdx = replaceVarargsSectionWithArray(pojoArgs, tmArgs, memberDesc, unwrapper); - if (argsOrErrorIdx instanceof Object[]) { - pojoArgsWithArray = (Object[]) argsOrErrorIdx; - } else { - return EmptyMemberAndArguments.noCompatibleOverload(((Integer) argsOrErrorIdx).intValue()); - } - if (bugfixed) { - if (typesFlags != 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(pojoArgsWithArray, memberDesc.getParamTypes(), typesFlags); - } - } else { - BeansWrapper.coerceBigDecimals(memberDesc.getParamTypes(), pojoArgsWithArray); - } - return new MemberAndArguments(memberDesc, pojoArgsWithArray); - } else { - return EmptyMemberAndArguments.from((EmptyCallableMemberDescriptor) maybeEmtpyMemberDesc, pojoArgs); - } - } - - /** - * Converts a flat argument list to one where the last argument is an array that collects the varargs, also - * re-unwraps the varargs to the component type. Note that this couldn't be done until we had the concrete - * member selected. - * - * @return An {@code Object[]} if everything went well, or an {@code Integer} the - * order (1-based index) of the argument that couldn't be unwrapped. - */ - private Object replaceVarargsSectionWithArray( - Object[] args, List modelArgs, CallableMemberDescriptor memberDesc, BeansWrapper unwrapper) - throws TemplateModelException { - final Class[] paramTypes = memberDesc.getParamTypes(); - final int paramCount = paramTypes.length; - final Class varArgsCompType = paramTypes[paramCount - 1].getComponentType(); - final int totalArgCount = args.length; - final int fixArgCount = paramCount - 1; - if (args.length != paramCount) { - Object[] packedArgs = new Object[paramCount]; - System.arraycopy(args, 0, packedArgs, 0, fixArgCount); - Object varargs = Array.newInstance(varArgsCompType, totalArgCount - fixArgCount); - for (int i = fixArgCount; i < totalArgCount; ++i) { - Object val = unwrapper.tryUnwrapTo((TemplateModel) modelArgs.get(i), varArgsCompType); - if (val == ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS) { - return Integer.valueOf(i + 1); - } - Array.set(varargs, i - fixArgCount, val); - } - packedArgs[fixArgCount] = varargs; - return packedArgs; - } else { - Object val = unwrapper.tryUnwrapTo((TemplateModel) modelArgs.get(fixArgCount), varArgsCompType); - if (val == ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS) { - return Integer.valueOf(fixArgCount + 1); - } - Object array = Array.newInstance(varArgsCompType, 1); - Array.set(array, 0, val); - args[fixArgCount] = array; - return args; - } - } - -} \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/ext/beans/PrimtiveArrayBackedReadOnlyList.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/beans/PrimtiveArrayBackedReadOnlyList.java b/src/main/java/freemarker/ext/beans/PrimtiveArrayBackedReadOnlyList.java deleted file mode 100644 index 84ab759..0000000 --- a/src/main/java/freemarker/ext/beans/PrimtiveArrayBackedReadOnlyList.java +++ /dev/null @@ -1,47 +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 freemarker.ext.beans; - -import java.lang.reflect.Array; -import java.util.AbstractList; - -/** - * Similar to {@link NonPrimitiveArrayBackedReadOnlyList}, but uses reflection so that it works with primitive arrays - * too. - */ -class PrimtiveArrayBackedReadOnlyList extends AbstractList { - - private final Object array; - - PrimtiveArrayBackedReadOnlyList(Object array) { - this.array = array; - } - - @Override - public Object get(int index) { - return Array.get(array, index); - } - - @Override - public int size() { - return Array.getLength(array); - } - -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/ext/beans/ReflectionCallableMemberDescriptor.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/beans/ReflectionCallableMemberDescriptor.java b/src/main/java/freemarker/ext/beans/ReflectionCallableMemberDescriptor.java deleted file mode 100644 index 1834c22..0000000 --- a/src/main/java/freemarker/ext/beans/ReflectionCallableMemberDescriptor.java +++ /dev/null @@ -1,95 +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 freemarker.ext.beans; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Member; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; - -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; - -/** - * The most commonly used {@link CallableMemberDescriptor} implementation. - */ -final class ReflectionCallableMemberDescriptor extends CallableMemberDescriptor { - - private final Member/*Method|Constructor*/ member; - - /** - * Don't modify this array! - */ - final Class[] paramTypes; - - ReflectionCallableMemberDescriptor(Method member, Class[] paramTypes) { - this.member = member; - this.paramTypes = paramTypes; - } - - ReflectionCallableMemberDescriptor(Constructor member, Class[] paramTypes) { - this.member = member; - this.paramTypes = paramTypes; - } - - @Override - TemplateModel invokeMethod(BeansWrapper bw, Object obj, Object[] args) - throws TemplateModelException, InvocationTargetException, IllegalAccessException { - return bw.invokeMethod(obj, (Method) member, args); - } - - @Override - Object invokeConstructor(BeansWrapper bw, Object[] args) - throws IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException { - return ((Constructor) member).newInstance(args); - } - - @Override - String getDeclaration() { - return _MethodUtil.toString(member); - } - - @Override - boolean isConstructor() { - return member instanceof Constructor; - } - - @Override - boolean isStatic() { - return (member.getModifiers() & Modifier.STATIC) != 0; - } - - @Override - boolean isVarargs() { - return _MethodUtil.isVarargs(member); - } - - @Override - Class[] getParamTypes() { - return paramTypes; - } - - @Override - String getName() { - return member.getName(); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/ext/beans/ResourceBundleModel.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/beans/ResourceBundleModel.java b/src/main/java/freemarker/ext/beans/ResourceBundleModel.java deleted file mode 100644 index 37e836f..0000000 --- a/src/main/java/freemarker/ext/beans/ResourceBundleModel.java +++ /dev/null @@ -1,189 +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 freemarker.ext.beans; - -import java.text.MessageFormat; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.MissingResourceException; -import java.util.ResourceBundle; -import java.util.Set; - -import freemarker.core._DelayedJQuote; -import freemarker.core._TemplateModelException; -import freemarker.ext.util.ModelFactory; -import freemarker.template.ObjectWrapper; -import freemarker.template.TemplateMethodModelEx; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; - -/** - * <p>A hash model that wraps a resource bundle. Makes it convenient to store - * localized content in the data model. It also acts as a method model that will - * take a resource key and arbitrary number of arguments and will apply - * {@link MessageFormat} with arguments on the string represented by the key.</p> - * - * <p>Typical usages:</p> - * <ul> - * <li><tt>bundle.resourceKey</tt> will retrieve the object from resource bundle - * with key <tt>resourceKey</tt></li> - * <li><tt>bundle("patternKey", arg1, arg2, arg3)</tt> will retrieve the string - * from resource bundle with key <tt>patternKey</tt>, and will use it as a pattern - * for MessageFormat with arguments arg1, arg2 and arg3</li> - * </ul> - */ -public class ResourceBundleModel - extends - BeanModel - implements - TemplateMethodModelEx { - static final ModelFactory FACTORY = - new ModelFactory() - { - public TemplateModel create(Object object, ObjectWrapper wrapper) { - return new ResourceBundleModel((ResourceBundle) object, (BeansWrapper) wrapper); - } - }; - - private Hashtable formats = null; - - public ResourceBundleModel(ResourceBundle bundle, BeansWrapper wrapper) { - super(bundle, wrapper); - } - - /** - * Overridden to invoke the getObject method of the resource bundle. - */ - @Override - protected TemplateModel invokeGenericGet(Map keyMap, Class clazz, String key) - throws TemplateModelException { - try { - return wrap(((ResourceBundle) object).getObject(key)); - } catch (MissingResourceException e) { - throw new _TemplateModelException(e, - "No ", new _DelayedJQuote(key), " key in the ResourceBundle. " - + "Note that conforming to the ResourceBundle Java API, this is an error and not just " - + "a missing sub-variable (a null)."); - } - } - - /** - * Returns true if this bundle contains no objects. - */ - @Override - public boolean isEmpty() { - return !((ResourceBundle) object).getKeys().hasMoreElements() && - super.isEmpty(); - } - - @Override - public int size() { - return keySet().size(); - } - - @Override - protected Set keySet() { - Set set = super.keySet(); - Enumeration e = ((ResourceBundle) object).getKeys(); - while (e.hasMoreElements()) { - set.add(e.nextElement()); - } - return set; - } - - /** - * Takes first argument as a resource key, looks up a string in resource bundle - * with this key, then applies a MessageFormat.format on the string with the - * rest of the arguments. The created MessageFormats are cached for later reuse. - */ - public Object exec(List arguments) - throws TemplateModelException { - // Must have at least one argument - the key - if (arguments.size() < 1) - throw new TemplateModelException("No message key was specified"); - // Read it - Iterator it = arguments.iterator(); - String key = unwrap((TemplateModel) it.next()).toString(); - try { - if (!it.hasNext()) { - return wrap(((ResourceBundle) object).getObject(key)); - } - - // Copy remaining arguments into an Object[] - int args = arguments.size() - 1; - Object[] params = new Object[args]; - for (int i = 0; i < args; ++i) - params[i] = unwrap((TemplateModel) it.next()); - - // Invoke format - return new StringModel(format(key, params), wrapper); - } catch (MissingResourceException e) { - throw new TemplateModelException("No such key: " + key); - } catch (Exception e) { - throw new TemplateModelException(e.getMessage()); - } - } - - /** - * Provides direct access to caching format engine from code (instead of from script). - */ - public String format(String key, Object[] params) - throws MissingResourceException { - // Check to see if we already have a cache for message formats - // and construct it if we don't - // NOTE: this block statement should be synchronized. However - // concurrent creation of two caches will have no harmful - // consequences, and we avoid a performance hit. - /* synchronized(this) */ - { - if (formats == null) - formats = new Hashtable(); - } - - MessageFormat format = null; - // Check to see if we already have a requested MessageFormat cached - // and construct it if we don't - // NOTE: this block statement should be synchronized. However - // concurrent creation of two formats will have no harmful - // consequences, and we avoid a performance hit. - /* synchronized(formats) */ - { - format = (MessageFormat) formats.get(key); - if (format == null) { - format = new MessageFormat(((ResourceBundle) object).getString(key)); - format.setLocale(getBundle().getLocale()); - formats.put(key, format); - } - } - - // Perform the formatting. We synchronize on it in case it - // contains date formatting, which is not thread-safe. - synchronized (format) { - return format.format(params); - } - } - - public ResourceBundle getBundle() { - return (ResourceBundle) object; - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/ext/beans/SequenceAdapter.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/beans/SequenceAdapter.java b/src/main/java/freemarker/ext/beans/SequenceAdapter.java deleted file mode 100644 index 734462a..0000000 --- a/src/main/java/freemarker/ext/beans/SequenceAdapter.java +++ /dev/null @@ -1,67 +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 freemarker.ext.beans; - -import java.util.AbstractList; - -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelAdapter; -import freemarker.template.TemplateModelException; -import freemarker.template.TemplateSequenceModel; -import freemarker.template.utility.UndeclaredThrowableException; - -/** - */ -class SequenceAdapter extends AbstractList implements TemplateModelAdapter { - private final BeansWrapper wrapper; - private final TemplateSequenceModel model; - - SequenceAdapter(TemplateSequenceModel model, BeansWrapper wrapper) { - this.model = model; - this.wrapper = wrapper; - } - - public TemplateModel getTemplateModel() { - return model; - } - - @Override - public int size() { - try { - return model.size(); - } catch (TemplateModelException e) { - throw new UndeclaredThrowableException(e); - } - } - - @Override - public Object get(int index) { - try { - return wrapper.unwrap(model.get(index)); - } catch (TemplateModelException e) { - throw new UndeclaredThrowableException(e); - } - } - - public TemplateSequenceModel getTemplateSequenceModel() { - return model; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/ext/beans/SetAdapter.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/beans/SetAdapter.java b/src/main/java/freemarker/ext/beans/SetAdapter.java deleted file mode 100644 index 010d1fc..0000000 --- a/src/main/java/freemarker/ext/beans/SetAdapter.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 freemarker.ext.beans; - -import java.util.Set; - -import freemarker.template.TemplateCollectionModel; - -/** - */ -class SetAdapter extends CollectionAdapter implements Set { - SetAdapter(TemplateCollectionModel model, BeansWrapper wrapper) { - super(model, wrapper); - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/ext/beans/SimpleMapModel.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/beans/SimpleMapModel.java b/src/main/java/freemarker/ext/beans/SimpleMapModel.java deleted file mode 100644 index fab7805..0000000 --- a/src/main/java/freemarker/ext/beans/SimpleMapModel.java +++ /dev/null @@ -1,122 +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 freemarker.ext.beans; - -import java.util.List; -import java.util.Map; - -import freemarker.core.CollectionAndSequence; -import freemarker.ext.util.ModelFactory; -import freemarker.ext.util.WrapperTemplateModel; -import freemarker.template.AdapterTemplateModel; -import freemarker.template.MapKeyValuePairIterator; -import freemarker.template.ObjectWrapper; -import freemarker.template.SimpleSequence; -import freemarker.template.TemplateCollectionModel; -import freemarker.template.TemplateHashModelEx2; -import freemarker.template.TemplateMethodModelEx; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; -import freemarker.template.TemplateModelWithAPISupport; -import freemarker.template.WrappingTemplateModel; -import freemarker.template.utility.RichObjectWrapper; - -/** - * Model used by {@link BeansWrapper} when <tt>simpleMapWrapper</tt> - * mode is enabled. Provides a simple hash model interface to the - * underlying map (does not copy like {@link freemarker.template.SimpleHash}), - * and a method interface to non-string keys. - */ -public class SimpleMapModel extends WrappingTemplateModel -implements TemplateHashModelEx2, TemplateMethodModelEx, AdapterTemplateModel, -WrapperTemplateModel, TemplateModelWithAPISupport { - static final ModelFactory FACTORY = - new ModelFactory() - { - public TemplateModel create(Object object, ObjectWrapper wrapper) { - return new SimpleMapModel((Map) object, (BeansWrapper) wrapper); - } - }; - - private final Map map; - - public SimpleMapModel(Map map, BeansWrapper wrapper) { - super(wrapper); - this.map = map; - } - - public TemplateModel get(String key) throws TemplateModelException { - 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 null; - } - } else if (!map.containsKey(key)) { - return null; - } - } - return wrap(val); - } - - public Object exec(List args) throws TemplateModelException { - Object key = ((BeansWrapper) getObjectWrapper()).unwrap((TemplateModel) args.get(0)); - Object value = map.get(key); - if (value == null && !map.containsKey(key)) { - return null; - } - return wrap(value); - } - - public boolean isEmpty() { - return map.isEmpty(); - } - - public int size() { - return map.size(); - } - - public TemplateCollectionModel keys() { - return new CollectionAndSequence(new SimpleSequence(map.keySet(), getObjectWrapper())); - } - - public TemplateCollectionModel values() { - return new CollectionAndSequence(new SimpleSequence(map.values(), getObjectWrapper())); - } - - public KeyValuePairIterator keyValuePairIterator() { - return new MapKeyValuePairIterator(map, getObjectWrapper()); - } - - public Object getAdaptedObject(Class hint) { - return map; - } - - public Object getWrappedObject() { - return map; - } - - public TemplateModel getAPI() throws TemplateModelException { - return ((RichObjectWrapper) getObjectWrapper()).wrapAsAPI(map); - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/ext/beans/SimpleMethod.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/beans/SimpleMethod.java b/src/main/java/freemarker/ext/beans/SimpleMethod.java deleted file mode 100644 index 4a42e71..0000000 --- a/src/main/java/freemarker/ext/beans/SimpleMethod.java +++ /dev/null @@ -1,175 +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 freemarker.ext.beans; - -import java.lang.reflect.Array; -import java.lang.reflect.Member; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import freemarker.core.TemplateMarkupOutputModel; -import freemarker.core._DelayedFTLTypeDescription; -import freemarker.core._DelayedOrdinal; -import freemarker.core._ErrorDescriptionBuilder; -import freemarker.core._TemplateModelException; -import freemarker.template.ObjectWrapperAndUnwrapper; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; -import freemarker.template.utility.ClassUtil; - -/** - * This class is used for as a base for non-overloaded method models and for constructors. - * (For overloaded methods and constructors see {@link OverloadedMethods}.) - */ -class SimpleMethod { - - static final String MARKUP_OUTPUT_TO_STRING_TIP - = "A markup output value can be converted to markup string like value?markup_string. " - + "But consider if the Java method whose argument it will be can handle markup strings properly."; - - private final Member member; - private final Class[] argTypes; - - protected SimpleMethod(Member member, Class[] argTypes) { - this.member = member; - this.argTypes = argTypes; - } - - Object[] unwrapArguments(List arguments, BeansWrapper wrapper) throws TemplateModelException { - if (arguments == null) { - arguments = Collections.EMPTY_LIST; - } - boolean isVarArg = _MethodUtil.isVarargs(member); - int typesLen = argTypes.length; - if (isVarArg) { - if (typesLen - 1 > arguments.size()) { - throw new _TemplateModelException( - _MethodUtil.invocationErrorMessageStart(member), - " takes at least ", Integer.valueOf(typesLen - 1), - typesLen - 1 == 1 ? " argument" : " arguments", ", but ", - Integer.valueOf(arguments.size()), " was given."); - } - } else if (typesLen != arguments.size()) { - throw new _TemplateModelException( - _MethodUtil.invocationErrorMessageStart(member), - " takes ", Integer.valueOf(typesLen), typesLen == 1 ? " argument" : " arguments", ", but ", - Integer.valueOf(arguments.size()), " was given."); - } - - Object[] args = unwrapArguments(arguments, argTypes, isVarArg, wrapper); - return args; - } - - private Object[] unwrapArguments(List args, Class[] argTypes, boolean isVarargs, - BeansWrapper w) - throws TemplateModelException { - if (args == null) return null; - - int typesLen = argTypes.length; - int argsLen = args.size(); - - Object[] unwrappedArgs = new Object[typesLen]; - - // Unwrap arguments: - Iterator it = args.iterator(); - int normalArgCnt = isVarargs ? typesLen - 1 : typesLen; - int argIdx = 0; - while (argIdx < normalArgCnt) { - Class argType = argTypes[argIdx]; - TemplateModel argVal = (TemplateModel) it.next(); - Object unwrappedArgVal = w.tryUnwrapTo(argVal, argType); - if (unwrappedArgVal == ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS) { - throw createArgumentTypeMismarchException(argIdx, argVal, argType); - } - if (unwrappedArgVal == null && argType.isPrimitive()) { - throw createNullToPrimitiveArgumentException(argIdx, argType); - } - - unwrappedArgs[argIdx++] = unwrappedArgVal; - } - if (isVarargs) { - // The last argType, which is the vararg type, wasn't processed yet. - - Class varargType = argTypes[typesLen - 1]; - Class varargItemType = varargType.getComponentType(); - if (!it.hasNext()) { - unwrappedArgs[argIdx++] = Array.newInstance(varargItemType, 0); - } else { - TemplateModel argVal = (TemplateModel) it.next(); - - Object unwrappedArgVal; - // We first try to treat the last argument as a vararg *array*. - // This is consistent to what OverloadedVarArgMethod does. - if (argsLen - argIdx == 1 - && (unwrappedArgVal = w.tryUnwrapTo(argVal, varargType)) - != ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS) { - // It was a vararg array. - unwrappedArgs[argIdx++] = unwrappedArgVal; - } else { - // It wasn't a vararg array, so we assume it's a vararg - // array *item*, possibly followed by further ones. - int varargArrayLen = argsLen - argIdx; - Object varargArray = Array.newInstance(varargItemType, varargArrayLen); - for (int varargIdx = 0; varargIdx < varargArrayLen; varargIdx++) { - TemplateModel varargVal = (TemplateModel) (varargIdx == 0 ? argVal : it.next()); - Object unwrappedVarargVal = w.tryUnwrapTo(varargVal, varargItemType); - if (unwrappedVarargVal == ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS) { - throw createArgumentTypeMismarchException( - argIdx + varargIdx, varargVal, varargItemType); - } - - if (unwrappedVarargVal == null && varargItemType.isPrimitive()) { - throw createNullToPrimitiveArgumentException(argIdx + varargIdx, varargItemType); - } - Array.set(varargArray, varargIdx, unwrappedVarargVal); - } - unwrappedArgs[argIdx++] = varargArray; - } - } - } - - return unwrappedArgs; - } - - private TemplateModelException createArgumentTypeMismarchException( - int argIdx, TemplateModel argVal, Class targetType) { - _ErrorDescriptionBuilder desc = new _ErrorDescriptionBuilder( - _MethodUtil.invocationErrorMessageStart(member), " couldn't be called: Can't convert the ", - new _DelayedOrdinal(Integer.valueOf(argIdx + 1)), - " argument's value to the target Java type, ", ClassUtil.getShortClassName(targetType), - ". The type of the actual value was: ", new _DelayedFTLTypeDescription(argVal)); - if (argVal instanceof TemplateMarkupOutputModel && (targetType.isAssignableFrom(String.class))) { - desc.tip(MARKUP_OUTPUT_TO_STRING_TIP); - } - return new _TemplateModelException(desc); - } - - private TemplateModelException createNullToPrimitiveArgumentException(int argIdx, Class targetType) { - return new _TemplateModelException( - _MethodUtil.invocationErrorMessageStart(member), " couldn't be called: The value of the ", - new _DelayedOrdinal(Integer.valueOf(argIdx + 1)), - " argument was null, but the target Java parameter type (", ClassUtil.getShortClassName(targetType), - ") is primitive and so can't store null."); - } - - protected Member getMember() { - return member; - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/ext/beans/SimpleMethodModel.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/beans/SimpleMethodModel.java b/src/main/java/freemarker/ext/beans/SimpleMethodModel.java deleted file mode 100644 index f7b347c..0000000 --- a/src/main/java/freemarker/ext/beans/SimpleMethodModel.java +++ /dev/null @@ -1,130 +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 freemarker.ext.beans; - -import java.lang.reflect.Member; -import java.lang.reflect.Method; -import java.util.Collections; -import java.util.List; - -import freemarker.core._UnexpectedTypeErrorExplainerTemplateModel; -import freemarker.template.SimpleNumber; -import freemarker.template.TemplateMethodModelEx; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; -import freemarker.template.TemplateSequenceModel; -import freemarker.template.utility.ClassUtil; - -/** - * A class that will wrap a reflected method call into a - * {@link freemarker.template.TemplateMethodModel} interface. - * It is used by {@link BeanModel} to wrap reflected method calls - * for non-overloaded methods. - */ -public final class SimpleMethodModel extends SimpleMethod - implements - TemplateMethodModelEx, - TemplateSequenceModel, - _UnexpectedTypeErrorExplainerTemplateModel { - private final Object object; - private final BeansWrapper wrapper; - - /** - * Creates a model for a specific method on a specific object. - * @param object the object to call the method on, or {@code null} for a static method. - * @param method the method that will be invoked. - * @param argTypes Either pass in {@code Method#getParameterTypes() method.getParameterTypes()} here, - * or reuse an earlier result of that call (for speed). Not {@code null}. - */ - SimpleMethodModel(Object object, Method method, Class[] argTypes, - BeansWrapper wrapper) { - super(method, argTypes); - this.object = object; - this.wrapper = wrapper; - } - - /** - * Invokes the method, passing it the arguments from the list. - */ - public Object exec(List arguments) - throws TemplateModelException { - try { - return wrapper.invokeMethod(object, (Method) getMember(), - unwrapArguments(arguments, wrapper)); - } catch (TemplateModelException e) { - throw e; - } catch (Exception e) { - throw _MethodUtil.newInvocationTemplateModelException(object, getMember(), e); - } - } - - public TemplateModel get(int index) throws TemplateModelException { - return (TemplateModel) exec(Collections.singletonList( - new SimpleNumber(Integer.valueOf(index)))); - } - - public int size() throws TemplateModelException { - throw new TemplateModelException( - "Getting the number of items or enumerating the items is not supported on this " - + ClassUtil.getFTLTypeDescription(this) + " value.\n" - + "(" - + "Hint 1: Maybe you wanted to call this method first and then do something with its return value. " - + "Hint 2: Getting items by intex possibly works, hence it's a \"+sequence\"." - + ")"); - } - - @Override - public String toString() { - return getMember().toString(); - } - - /** - * Implementation of experimental interface; don't use it, no backward compatibility guarantee! - */ - public Object[] explainTypeError(Class[] expectedClasses) { - final Member member = getMember(); - if (!(member instanceof Method)) { - return null; // This shouldn't occur - } - Method m = (Method) member; - - final Class returnType = m.getReturnType(); - if (returnType == null || returnType == void.class || returnType == Void.class) { - return null; // Calling it won't help - } - - String mName = m.getName(); - if (mName.startsWith("get") && mName.length() > 3 && Character.isUpperCase(mName.charAt(3)) - && (m.getParameterTypes().length == 0)) { - return new Object[] { - "Maybe using obj.something instead of obj.getSomething will yield the desired value." }; - } else if (mName.startsWith("is") && mName.length() > 2 && Character.isUpperCase(mName.charAt(2)) - && (m.getParameterTypes().length == 0)) { - return new Object[] { - "Maybe using obj.something instead of obj.isSomething will yield the desired value." }; - } else { - return new Object[] { - "Maybe using obj.something(", - (m.getParameterTypes().length != 0 ? "params" : ""), - ") instead of obj.something will yield the desired value" }; - } - } - -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/ext/beans/SingletonCustomizer.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/beans/SingletonCustomizer.java b/src/main/java/freemarker/ext/beans/SingletonCustomizer.java deleted file mode 100644 index 89af09c..0000000 --- a/src/main/java/freemarker/ext/beans/SingletonCustomizer.java +++ /dev/null @@ -1,51 +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 freemarker.ext.beans; - -import freemarker.template.ObjectWrapper; - -/** - * Marker interface useful when used together with {@link MethodAppearanceFineTuner} and such customizer objects, to - * indicate that it <b>doesn't contain reference to the {@link ObjectWrapper}</b> (so beware with non-static inner - * classes) and can be and should be used in call introspection cache keys. This also implies that you won't - * create many instances of the class, rather just reuse the same (or same few) instances over and over. Furthermore, - * the instances must be thread-safe. The typical pattern in which this instance should be used is like this: - * - * <pre>static class MyMethodAppearanceFineTuner implements MethodAppearanceFineTuner, SingletonCustomizer { - * - * // This is the singleton: - * static final MyMethodAppearanceFineTuner INSTANCE = new MyMethodAppearanceFineTuner(); - * - * // Private, so it can't be constructed from outside this class. - * private MyMethodAppearanceFineTuner() { } - * - * @Override - * public void fineTuneMethodAppearance(...) { - * // Do something here, only using the parameters and maybe some other singletons. - * ... - * } - * - * }</pre> - * - * @since 2.3.21 - */ -public interface SingletonCustomizer { - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/ext/beans/StaticModel.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/beans/StaticModel.java b/src/main/java/freemarker/ext/beans/StaticModel.java deleted file mode 100644 index 5c11719..0000000 --- a/src/main/java/freemarker/ext/beans/StaticModel.java +++ /dev/null @@ -1,178 +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 freemarker.ext.beans; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import freemarker.template.TemplateCollectionModel; -import freemarker.template.TemplateHashModelEx; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; - -/** - * Wraps the static fields and methods of a class in a - * {@link freemarker.template.TemplateHashModel}. - * Fields are wrapped using {@link BeansWrapper#wrap(Object)}, and - * methods are wrapped into an appropriate {@link freemarker.template.TemplateMethodModelEx} instance. - * Unfortunately, there is currently no support for bean property-style - * calls of static methods, similar to that in {@link BeanModel}. - */ -final class StaticModel implements TemplateHashModelEx { - private static final Logger LOG = LoggerFactory.getLogger("freemarker.beans"); - - private final Class clazz; - private final BeansWrapper wrapper; - private final Map map = new HashMap(); - - StaticModel(Class clazz, BeansWrapper wrapper) throws TemplateModelException { - this.clazz = clazz; - this.wrapper = wrapper; - populate(); - } - - /** - * Returns the field or method named by the <tt>key</tt> - * parameter. - */ - @Override - public TemplateModel get(String key) throws TemplateModelException { - Object model = map.get(key); - // Simple method, overloaded method or final field -- these have cached - // template models - if (model instanceof TemplateModel) - return (TemplateModel) model; - // Non-final field; this must be evaluated on each call. - if (model instanceof Field) { - try { - return wrapper.getOuterIdentity().wrap(((Field) model).get(null)); - } catch (IllegalAccessException e) { - throw new TemplateModelException( - "Illegal access for field " + key + " of class " + clazz.getName()); - } - } - - throw new TemplateModelException( - "No such key: " + key + " in class " + clazz.getName()); - } - - /** - * Returns true if there is at least one public static - * field or method in the underlying class. - */ - @Override - public boolean isEmpty() { - return map.isEmpty(); - } - - @Override - public int size() { - return map.size(); - } - - @Override - public TemplateCollectionModel keys() throws TemplateModelException { - return (TemplateCollectionModel) wrapper.getOuterIdentity().wrap(map.keySet()); - } - - @Override - public TemplateCollectionModel values() throws TemplateModelException { - return (TemplateCollectionModel) wrapper.getOuterIdentity().wrap(map.values()); - } - - private void populate() throws TemplateModelException { - if (!Modifier.isPublic(clazz.getModifiers())) { - throw new TemplateModelException( - "Can't wrap the non-public class " + clazz.getName()); - } - - if (wrapper.getExposureLevel() == BeansWrapper.EXPOSE_NOTHING) { - return; - } - - Field[] fields = clazz.getFields(); - for (int i = 0; i < fields.length; ++i) { - Field field = fields[i]; - int mod = field.getModifiers(); - if (Modifier.isPublic(mod) && Modifier.isStatic(mod)) { - if (Modifier.isFinal(mod)) - try { - // public static final fields are evaluated once and - // stored in the map - map.put(field.getName(), wrapper.getOuterIdentity().wrap(field.get(null))); - } catch (IllegalAccessException e) { - // Intentionally ignored - } else - // This is a special flagging value: Field in the map means - // that this is a non-final field, and it must be evaluated - // on each get() call. - map.put(field.getName(), field); - } - } - if (wrapper.getExposureLevel() < BeansWrapper.EXPOSE_PROPERTIES_ONLY) { - Method[] methods = clazz.getMethods(); - for (int i = 0; i < methods.length; ++i) { - Method method = methods[i]; - int mod = method.getModifiers(); - if (Modifier.isPublic(mod) && Modifier.isStatic(mod) - && wrapper.getClassIntrospector().isAllowedToExpose(method)) { - String name = method.getName(); - Object obj = map.get(name); - if (obj instanceof Method) { - OverloadedMethods overloadedMethods = new OverloadedMethods(wrapper.is2321Bugfixed()); - overloadedMethods.addMethod((Method) obj); - overloadedMethods.addMethod(method); - map.put(name, overloadedMethods); - } else if (obj instanceof OverloadedMethods) { - OverloadedMethods overloadedMethods = (OverloadedMethods) obj; - overloadedMethods.addMethod(method); - } else { - if (obj != null) { - if (LOG.isInfoEnabled()) { - LOG.info("Overwriting value [" + obj + "] for " + - " key '" + name + "' with [" + method + - "] in static model for " + clazz.getName()); - } - } - map.put(name, method); - } - } - } - for (Iterator entries = map.entrySet().iterator(); entries.hasNext(); ) { - Map.Entry entry = (Map.Entry) entries.next(); - Object value = entry.getValue(); - if (value instanceof Method) { - Method method = (Method) value; - entry.setValue(new SimpleMethodModel(null, method, - method.getParameterTypes(), wrapper)); - } else if (value instanceof OverloadedMethods) { - entry.setValue(new OverloadedMethodsModel(null, (OverloadedMethods) value, wrapper)); - } - } - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/ext/beans/StaticModels.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/beans/StaticModels.java b/src/main/java/freemarker/ext/beans/StaticModels.java deleted file mode 100644 index f4dc8cc..0000000 --- a/src/main/java/freemarker/ext/beans/StaticModels.java +++ /dev/null @@ -1,43 +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 freemarker.ext.beans; - -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; - -/** - * Utility class for instantiating {@link StaticModel} instances from - * templates. If your template's data model contains an instance of - * StaticModels (named, say <tt>StaticModels</tt>), then you can - * instantiate an arbitrary StaticModel using get syntax (i.e. - * <tt>StaticModels["java.lang.System"].currentTimeMillis()</tt>). - */ -class StaticModels extends ClassBasedModelFactory { - - StaticModels(BeansWrapper wrapper) { - super(wrapper); - } - - @Override - protected TemplateModel createModel(Class clazz) - throws TemplateModelException { - return new StaticModel(clazz, getWrapper()); - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/ext/beans/StringModel.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/beans/StringModel.java b/src/main/java/freemarker/ext/beans/StringModel.java deleted file mode 100644 index 4619e4f..0000000 --- a/src/main/java/freemarker/ext/beans/StringModel.java +++ /dev/null @@ -1,62 +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 freemarker.ext.beans; - -import freemarker.ext.util.ModelFactory; -import freemarker.template.ObjectWrapper; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateScalarModel; - -/** - * Subclass of {@link BeanModel} that exposes the return value of the {@link - * java.lang.Object#toString()} method through the {@link TemplateScalarModel} - * interface. - */ -public class StringModel extends BeanModel -implements TemplateScalarModel { - static final ModelFactory FACTORY = - new ModelFactory() - { - public TemplateModel create(Object object, ObjectWrapper wrapper) { - return new StringModel(object, (BeansWrapper) wrapper); - } - }; - - /** - * Creates a new model that wraps the specified object with BeanModel + scalar - * functionality. - * @param object the 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 StringModel(Object object, BeansWrapper wrapper) { - super(object, wrapper); - } - - /** - * Returns the result of calling {@link Object#toString()} on the wrapped - * object. - */ - public String getAsString() { - return object.toString(); - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/ext/beans/TypeFlags.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/beans/TypeFlags.java b/src/main/java/freemarker/ext/beans/TypeFlags.java deleted file mode 100644 index 3507519..0000000 --- a/src/main/java/freemarker/ext/beans/TypeFlags.java +++ /dev/null @@ -1,130 +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 freemarker.ext.beans; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Flag values and masks for "type flags". "Type flags" is a set of bits that store information about the possible - * destination types at a parameter position of overloaded methods. - */ -class TypeFlags { - - /** - * Indicates that the unwrapping hint will not be a specific numerical type; it must not be set if there's no - * numerical type at the given parameter index. - */ - static final int WIDENED_NUMERICAL_UNWRAPPING_HINT = 1; - - static final int BYTE = 4; - static final int SHORT = 8; - static final int INTEGER = 16; - static final int LONG = 32; - static final int FLOAT = 64; - static final int DOUBLE = 128; - static final int BIG_INTEGER = 256; - static final int BIG_DECIMAL = 512; - static final int UNKNOWN_NUMERICAL_TYPE = 1024; - - static final int ACCEPTS_NUMBER = 0x800; - static final int ACCEPTS_DATE = 0x1000; - static final int ACCEPTS_STRING = 0x2000; - static final int ACCEPTS_BOOLEAN = 0x4000; - static final int ACCEPTS_MAP = 0x8000; - static final int ACCEPTS_LIST = 0x10000; - static final int ACCEPTS_SET = 0x20000; - static final int ACCEPTS_ARRAY = 0x40000; - - /** - * Indicates the presence of the char or Character type - */ - static final int CHARACTER = 0x80000; - - static final int ACCEPTS_ANY_OBJECT = ACCEPTS_NUMBER | ACCEPTS_DATE | ACCEPTS_STRING | ACCEPTS_BOOLEAN - | ACCEPTS_MAP | ACCEPTS_LIST | ACCEPTS_SET | ACCEPTS_ARRAY; - - static final int MASK_KNOWN_INTEGERS = BYTE | SHORT | INTEGER | LONG | BIG_INTEGER; - static final int MASK_KNOWN_NONINTEGERS = FLOAT | DOUBLE | BIG_DECIMAL; - static final int MASK_ALL_KNOWN_NUMERICALS = MASK_KNOWN_INTEGERS | MASK_KNOWN_NONINTEGERS; - static final int MASK_ALL_NUMERICALS = MASK_ALL_KNOWN_NUMERICALS | UNKNOWN_NUMERICAL_TYPE; - - static int classToTypeFlags(Class pClass) { - // We start with the most frequent cases - if (pClass == Object.class) { - return ACCEPTS_ANY_OBJECT; - } else if (pClass == String.class) { - return ACCEPTS_STRING; - } else if (pClass.isPrimitive()) { - if (pClass == Integer.TYPE) return INTEGER | ACCEPTS_NUMBER; - else if (pClass == Long.TYPE) return LONG | ACCEPTS_NUMBER; - else if (pClass == Double.TYPE) return DOUBLE | ACCEPTS_NUMBER; - else if (pClass == Float.TYPE) return FLOAT | ACCEPTS_NUMBER; - else if (pClass == Byte.TYPE) return BYTE | ACCEPTS_NUMBER; - else if (pClass == Short.TYPE) return SHORT | ACCEPTS_NUMBER; - else if (pClass == Character.TYPE) return CHARACTER; - else if (pClass == Boolean.TYPE) return ACCEPTS_BOOLEAN; - else return 0; - } else if (Number.class.isAssignableFrom(pClass)) { - if (pClass == Integer.class) return INTEGER | ACCEPTS_NUMBER; - else if (pClass == Long.class) return LONG | ACCEPTS_NUMBER; - else if (pClass == Double.class) return DOUBLE | ACCEPTS_NUMBER; - else if (pClass == Float.class) return FLOAT | ACCEPTS_NUMBER; - else if (pClass == Byte.class) return BYTE | ACCEPTS_NUMBER; - else if (pClass == Short.class) return SHORT | ACCEPTS_NUMBER; - else if (BigDecimal.class.isAssignableFrom(pClass)) return BIG_DECIMAL | ACCEPTS_NUMBER; - else if (BigInteger.class.isAssignableFrom(pClass)) return BIG_INTEGER | ACCEPTS_NUMBER; - else return UNKNOWN_NUMERICAL_TYPE | ACCEPTS_NUMBER; - } else if (pClass.isArray()) { - return ACCEPTS_ARRAY; - } else { - int flags = 0; - if (pClass.isAssignableFrom(String.class)) { - flags |= ACCEPTS_STRING; - } - if (pClass.isAssignableFrom(Date.class)) { - flags |= ACCEPTS_DATE; - } - if (pClass.isAssignableFrom(Boolean.class)) { - flags |= ACCEPTS_BOOLEAN; - } - if (pClass.isAssignableFrom(Map.class)) { - flags |= ACCEPTS_MAP; - } - if (pClass.isAssignableFrom(List.class)) { - flags |= ACCEPTS_LIST; - } - if (pClass.isAssignableFrom(Set.class)) { - flags |= ACCEPTS_SET; - } - - if (pClass == Character.class) { - flags |= CHARACTER; - } - - return flags; - } - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/ext/beans/UnsafeMethods.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/beans/UnsafeMethods.java b/src/main/java/freemarker/ext/beans/UnsafeMethods.java deleted file mode 100644 index 6d398ec..0000000 --- a/src/main/java/freemarker/ext/beans/UnsafeMethods.java +++ /dev/null @@ -1,114 +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 freemarker.ext.beans; - -import java.io.InputStream; -import java.lang.reflect.Method; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.StringTokenizer; - -import freemarker.template.utility.ClassUtil; - -class UnsafeMethods { - - private static final Set UNSAFE_METHODS = createUnsafeMethodsSet(); - - private UnsafeMethods() { } - - static boolean isUnsafeMethod(Method method) { - return UNSAFE_METHODS.contains(method); - } - - private static final Set createUnsafeMethodsSet() { - Properties props = new Properties(); - InputStream in = BeansWrapper.class.getResourceAsStream("unsafeMethods.properties"); - if (in != null) { - String methodSpec = null; - try { - try { - props.load(in); - } finally { - in.close(); - } - Set set = new HashSet(props.size() * 4 / 3, 1f); - Map primClasses = createPrimitiveClassesMap(); - for (Iterator iterator = props.keySet().iterator(); iterator.hasNext(); ) { - methodSpec = (String) iterator.next(); - try { - set.add(parseMethodSpec(methodSpec, primClasses)); - } catch (ClassNotFoundException e) { - if (ClassIntrospector.DEVELOPMENT_MODE) { - throw e; - } - } catch (NoSuchMethodException e) { - if (ClassIntrospector.DEVELOPMENT_MODE) { - throw e; - } - } - } - return set; - } catch (Exception e) { - throw new RuntimeException("Could not load unsafe method " + methodSpec + " " + e.getClass().getName() + " " + e.getMessage()); - } - } - return Collections.EMPTY_SET; - } - - private static Method parseMethodSpec(String methodSpec, Map primClasses) - throws ClassNotFoundException, - NoSuchMethodException { - int brace = methodSpec.indexOf('('); - int dot = methodSpec.lastIndexOf('.', brace); - Class clazz = ClassUtil.forName(methodSpec.substring(0, dot)); - String methodName = methodSpec.substring(dot + 1, brace); - String argSpec = methodSpec.substring(brace + 1, methodSpec.length() - 1); - StringTokenizer tok = new StringTokenizer(argSpec, ","); - int argcount = tok.countTokens(); - Class[] argTypes = new Class[argcount]; - for (int i = 0; i < argcount; i++) { - String argClassName = tok.nextToken(); - argTypes[i] = (Class) primClasses.get(argClassName); - if (argTypes[i] == null) { - argTypes[i] = ClassUtil.forName(argClassName); - } - } - return clazz.getMethod(methodName, argTypes); - } - - private static Map createPrimitiveClassesMap() { - Map map = new HashMap(); - map.put("boolean", Boolean.TYPE); - map.put("byte", Byte.TYPE); - map.put("char", Character.TYPE); - map.put("short", Short.TYPE); - map.put("int", Integer.TYPE); - map.put("long", Long.TYPE); - map.put("float", Float.TYPE); - map.put("double", Double.TYPE); - return map; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/ext/beans/_BeansAPI.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/beans/_BeansAPI.java b/src/main/java/freemarker/ext/beans/_BeansAPI.java deleted file mode 100644 index e0a2d94..0000000 --- a/src/main/java/freemarker/ext/beans/_BeansAPI.java +++ /dev/null @@ -1,222 +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 freemarker.ext.beans; - -import java.lang.ref.Reference; -import java.lang.ref.ReferenceQueue; -import java.lang.ref.WeakReference; -import java.lang.reflect.Array; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import freemarker.core.BugException; -import freemarker.template.DefaultObjectWrapper; -import freemarker.template.TemplateModelException; -import freemarker.template.utility.CollectionUtils; - -/** - * For internal use only; don't depend on this, there's no backward compatibility guarantee at all! - * This class is to work around the lack of module system in Java, i.e., so that other FreeMarker packages can - * access things inside this package that users shouldn't. - */ -public class _BeansAPI { - - private _BeansAPI() { } - - public static Object newInstance(Class<?> pClass, Object[] args, BeansWrapper bw) - throws NoSuchMethodException, IllegalArgumentException, InstantiationException, - IllegalAccessException, InvocationTargetException, TemplateModelException { - return newInstance(getConstructorDescriptor(pClass, args), args, bw); - } - - /** - * Gets the constructor that matches the types of the arguments the best. So this is more - * than what the Java reflection API provides in that it can handle overloaded constructors. This re-uses the - * overloaded method selection logic of {@link BeansWrapper}. - */ - private static CallableMemberDescriptor getConstructorDescriptor(Class<?> pClass, Object[] args) - throws NoSuchMethodException { - if (args == null) args = CollectionUtils.EMPTY_OBJECT_ARRAY; - - final ArgumentTypes argTypes = new ArgumentTypes(args, true); - final List<ReflectionCallableMemberDescriptor> fixedArgMemberDescs - = new ArrayList<ReflectionCallableMemberDescriptor>(); - final List<ReflectionCallableMemberDescriptor> varArgsMemberDescs - = new ArrayList<ReflectionCallableMemberDescriptor>(); - final Constructor<?>[] constrs = pClass.getConstructors(); - for (int i = 0; i < constrs.length; i++) { - Constructor<?> constr = constrs[i]; - ReflectionCallableMemberDescriptor memberDesc = new ReflectionCallableMemberDescriptor(constr, constr.getParameterTypes()); - if (!_MethodUtil.isVarargs(constr)) { - fixedArgMemberDescs.add(memberDesc); - } else { - varArgsMemberDescs.add(memberDesc); - } - } - - MaybeEmptyCallableMemberDescriptor contrDesc = argTypes.getMostSpecific(fixedArgMemberDescs, false); - if (contrDesc == EmptyCallableMemberDescriptor.NO_SUCH_METHOD) { - contrDesc = argTypes.getMostSpecific(varArgsMemberDescs, true); - } - - if (contrDesc instanceof EmptyCallableMemberDescriptor) { - if (contrDesc == EmptyCallableMemberDescriptor.NO_SUCH_METHOD) { - throw new NoSuchMethodException( - "There's no public " + pClass.getName() - + " constructor with compatible parameter list."); - } else if (contrDesc == EmptyCallableMemberDescriptor.AMBIGUOUS_METHOD) { - throw new NoSuchMethodException( - "There are multiple public " + pClass.getName() - + " constructors that match the compatible parameter list with the same preferability."); - } else { - throw new NoSuchMethodException(); - } - } else { - return (CallableMemberDescriptor) contrDesc; - } - } - - private static Object newInstance(CallableMemberDescriptor constrDesc, Object[] args, BeansWrapper bw) - throws InstantiationException, IllegalAccessException, InvocationTargetException, IllegalArgumentException, - TemplateModelException { - if (args == null) args = CollectionUtils.EMPTY_OBJECT_ARRAY; - - final Object[] packedArgs; - if (constrDesc.isVarargs()) { - // We have to put all the varargs arguments into a single array argument. - - final Class<?>[] paramTypes = constrDesc.getParamTypes(); - final int fixedArgCnt = paramTypes.length - 1; - - packedArgs = new Object[fixedArgCnt + 1]; - for (int i = 0; i < fixedArgCnt; i++) { - packedArgs[i] = args[i]; - } - - final Class<?> compType = paramTypes[fixedArgCnt].getComponentType(); - final int varArgCnt = args.length - fixedArgCnt; - final Object varArgsArray = Array.newInstance(compType, varArgCnt); - for (int i = 0; i < varArgCnt; i++) { - Array.set(varArgsArray, i, args[fixedArgCnt + i]); - } - packedArgs[fixedArgCnt] = varArgsArray; - } else { - packedArgs = args; - } - - return constrDesc.invokeConstructor(bw, packedArgs); - } - - /** - * Contains the common parts of the singleton management for {@link BeansWrapper} and {@link DefaultObjectWrapper}. - * - * @param beansWrapperSubclassFactory Creates a <em>new</em> read-only object wrapper of the desired - * {@link BeansWrapper} subclass. - */ - public static <BW extends BeansWrapper, BWC extends BeansWrapperConfiguration> BW getBeansWrapperSubclassSingleton( - BWC settings, - Map<ClassLoader, Map<BWC, WeakReference<BW>>> instanceCache, - ReferenceQueue<BW> instanceCacheRefQue, - _BeansWrapperSubclassFactory<BW, BWC> beansWrapperSubclassFactory) { - // BeansWrapper can't be cached across different Thread Context Class Loaders (TCCL), because the result of - // a class name (String) to Class mappings depends on it, and the staticModels and enumModels need that. - // (The ClassIntrospector doesn't have to consider the TCCL, as it only works with Class-es, not class - // names.) - ClassLoader tccl = Thread.currentThread().getContextClassLoader(); - - Reference<BW> instanceRef; - Map<BWC, WeakReference<BW>> tcclScopedCache; - synchronized (instanceCache) { - tcclScopedCache = instanceCache.get(tccl); - if (tcclScopedCache == null) { - tcclScopedCache = new HashMap<BWC, WeakReference<BW>>(); - instanceCache.put(tccl, tcclScopedCache); - instanceRef = null; - } else { - instanceRef = tcclScopedCache.get(settings); - } - } - - BW instance = instanceRef != null ? instanceRef.get() : null; - if (instance != null) { // cache hit - return instance; - } - // cache miss - - settings = clone(settings); // prevent any aliasing issues - instance = beansWrapperSubclassFactory.create(settings); - if (!instance.isWriteProtected()) { - throw new BugException(); - } - - synchronized (instanceCache) { - instanceRef = tcclScopedCache.get(settings); - BW concurrentInstance = instanceRef != null ? instanceRef.get() : null; - if (concurrentInstance == null) { - tcclScopedCache.put(settings, new WeakReference<BW>(instance, instanceCacheRefQue)); - } else { - instance = concurrentInstance; - } - } - - removeClearedReferencesFromCache(instanceCache, instanceCacheRefQue); - - return instance; - } - - @SuppressWarnings("unchecked") - private static <BWC extends BeansWrapperConfiguration> BWC clone(BWC settings) { - return (BWC) settings.clone(true); - } - - private static <BW extends BeansWrapper, BWC extends BeansWrapperConfiguration> - void removeClearedReferencesFromCache( - Map<ClassLoader, Map<BWC, WeakReference<BW>>> instanceCache, - ReferenceQueue<BW> instanceCacheRefQue) { - Reference<? extends BW> clearedRef; - while ((clearedRef = instanceCacheRefQue.poll()) != null) { - synchronized (instanceCache) { - findClearedRef: for (Map<BWC, WeakReference<BW>> tcclScopedCache : instanceCache.values()) { - for (Iterator<WeakReference<BW>> it2 = tcclScopedCache.values().iterator(); it2.hasNext(); ) { - if (it2.next() == clearedRef) { - it2.remove(); - break findClearedRef; - } - } - } - } // sync - } // while poll - } - - /** - * For internal use only; don't depend on this, there's no backward compatibility guarantee at all! - */ - public interface _BeansWrapperSubclassFactory<BW extends BeansWrapper, BWC extends BeansWrapperConfiguration> { - - /** Creates a new read-only {@link BeansWrapper}; used for {@link BeansWrapperBuilder} and such. */ - BW create(BWC sa); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/ext/beans/_EnumModels.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/beans/_EnumModels.java b/src/main/java/freemarker/ext/beans/_EnumModels.java deleted file mode 100644 index ff51bfb..0000000 --- a/src/main/java/freemarker/ext/beans/_EnumModels.java +++ /dev/null @@ -1,54 +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 freemarker.ext.beans; - -import java.util.LinkedHashMap; -import java.util.Map; - -import freemarker.template.TemplateModel; - -/** - * Don't use this class; it's only public to work around Google App Engine Java - * compliance issues. FreeMarker developers only: treat this class as package-visible. - */ -public class _EnumModels extends ClassBasedModelFactory { - - public _EnumModels(BeansWrapper wrapper) { - super(wrapper); - } - - @Override - protected TemplateModel createModel(Class clazz) { - Object[] obj = clazz.getEnumConstants(); - if (obj == null) { - // Return null - it'll manifest itself as undefined in the template. - // We're doing this rather than throw an exception as this way - // people can use someEnumModel?default({}) to gracefully fall back - // to an empty hash if they want to. - return null; - } - Map map = new LinkedHashMap(); - for (int i = 0; i < obj.length; i++) { - Enum value = (Enum) obj[i]; - map.put(value.name(), value); - } - return new SimpleMapModel(map, getWrapper()); - } -}
