http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/ext/servlet/HttpRequestHashModel.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/servlet/HttpRequestHashModel.java b/src/main/java/freemarker/ext/servlet/HttpRequestHashModel.java deleted file mode 100644 index 6ed9e51..0000000 --- a/src/main/java/freemarker/ext/servlet/HttpRequestHashModel.java +++ /dev/null @@ -1,106 +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.servlet; - -import java.util.ArrayList; -import java.util.Enumeration; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import freemarker.template.ObjectWrapper; -import freemarker.template.ObjectWrapperAndUnwrapper; -import freemarker.template.SimpleCollection; -import freemarker.template.TemplateCollectionModel; -import freemarker.template.TemplateHashModelEx; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; - -/** - * TemplateHashModel wrapper for a HttpServletRequest attributes. - */ -public final class HttpRequestHashModel implements TemplateHashModelEx { - private final HttpServletRequest request; - private final HttpServletResponse response; - private final ObjectWrapper wrapper; - - /** - * @param wrapper - * Should be an {@link ObjectWrapperAndUnwrapper}, or else some features might won't work properly. (It's - * declared as {@link ObjectWrapper} only for backward compatibility.) - */ - public HttpRequestHashModel( - HttpServletRequest request, ObjectWrapper wrapper) { - this(request, null, wrapper); - } - - public HttpRequestHashModel( - HttpServletRequest request, HttpServletResponse response, - ObjectWrapper wrapper) { - this.request = request; - this.response = response; - this.wrapper = wrapper; - } - - public TemplateModel get(String key) throws TemplateModelException { - return wrapper.wrap(request.getAttribute(key)); - } - - public boolean isEmpty() { - return !request.getAttributeNames().hasMoreElements(); - } - - public int size() { - int result = 0; - for (Enumeration enumeration = request.getAttributeNames(); enumeration.hasMoreElements(); ) { - enumeration.nextElement(); - ++result; - } - return result; - } - - public TemplateCollectionModel keys() { - ArrayList keys = new ArrayList(); - for (Enumeration enumeration = request.getAttributeNames(); enumeration.hasMoreElements(); ) { - keys.add(enumeration.nextElement()); - } - return new SimpleCollection(keys.iterator()); - } - - public TemplateCollectionModel values() { - ArrayList values = new ArrayList(); - for (Enumeration enumeration = request.getAttributeNames(); enumeration.hasMoreElements(); ) { - values.add(request.getAttribute((String) enumeration.nextElement())); - } - return new SimpleCollection(values.iterator(), wrapper); - } - - public HttpServletRequest getRequest() { - return request; - } - - public HttpServletResponse getResponse() { - return response; - } - - public ObjectWrapper getObjectWrapper() { - return wrapper; - } -}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/ext/servlet/HttpRequestParametersHashModel.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/servlet/HttpRequestParametersHashModel.java b/src/main/java/freemarker/ext/servlet/HttpRequestParametersHashModel.java deleted file mode 100644 index 4b710a1..0000000 --- a/src/main/java/freemarker/ext/servlet/HttpRequestParametersHashModel.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.servlet; - -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.List; - -import javax.servlet.http.HttpServletRequest; - -import freemarker.template.SimpleCollection; -import freemarker.template.SimpleScalar; -import freemarker.template.TemplateCollectionModel; -import freemarker.template.TemplateHashModelEx; -import freemarker.template.TemplateModel; - -/** - * TemplateHashModel wrapper for a HttpServletRequest parameters. - */ - -public class HttpRequestParametersHashModel - implements - TemplateHashModelEx { - private final HttpServletRequest request; - private List keys; - - public HttpRequestParametersHashModel(HttpServletRequest request) { - this.request = request; - } - - public TemplateModel get(String key) { - String value = request.getParameter(key); - return value == null ? null : new SimpleScalar(value); - } - - public boolean isEmpty() { - return !request.getParameterNames().hasMoreElements(); - } - - public int size() { - return getKeys().size(); - } - - public TemplateCollectionModel keys() { - return new SimpleCollection(getKeys().iterator()); - } - - public TemplateCollectionModel values() { - final Iterator iter = getKeys().iterator(); - return new SimpleCollection( - new Iterator() { - public boolean hasNext() { - return iter.hasNext(); - } - public Object next() { - return request.getParameter((String) iter.next()); - } - public void remove() { - throw new UnsupportedOperationException(); - } - }); - } - - protected String transcode(String string) { - return string; - } - - private synchronized List getKeys() { - if (keys == null) { - keys = new ArrayList(); - for (Enumeration enumeration = request.getParameterNames(); enumeration.hasMoreElements(); ) { - keys.add(enumeration.nextElement()); - } - } - return keys; - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/ext/servlet/HttpSessionHashModel.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/servlet/HttpSessionHashModel.java b/src/main/java/freemarker/ext/servlet/HttpSessionHashModel.java deleted file mode 100644 index 6fd3a1e..0000000 --- a/src/main/java/freemarker/ext/servlet/HttpSessionHashModel.java +++ /dev/null @@ -1,111 +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.servlet; - -import java.io.Serializable; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import freemarker.template.ObjectWrapper; -import freemarker.template.TemplateHashModel; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; - -/** - * TemplateHashModel wrapper for a HttpSession attributes. - */ - -public final class HttpSessionHashModel implements TemplateHashModel, Serializable { - private static final long serialVersionUID = 1L; - private transient HttpSession session; - private transient final ObjectWrapper wrapper; - - // These are required for lazy initializing session - private transient final FreemarkerServlet servlet; - private transient final HttpServletRequest request; - private transient final HttpServletResponse response; - - /** - * Use this constructor when the session already exists. - * @param session the session - * @param wrapper an object wrapper used to wrap session attributes - */ - public HttpSessionHashModel(HttpSession session, ObjectWrapper wrapper) { - this.session = session; - this.wrapper = wrapper; - - this.servlet = null; - this.request = null; - this.response = null; - } - - /** - * Use this constructor when the session isn't already created. It is passed - * enough parameters so that the session can be properly initialized after - * it's detected that it was created. - * @param servlet the FreemarkerServlet that created this model. If the - * model is not created through FreemarkerServlet, leave this argument as - * null. - * @param request the actual request - * @param response the actual response - * @param wrapper an object wrapper used to wrap session attributes - */ - public HttpSessionHashModel(FreemarkerServlet servlet, HttpServletRequest request, HttpServletResponse response, ObjectWrapper wrapper) { - this.wrapper = wrapper; - - this.servlet = servlet; - this.request = request; - this.response = response; - } - - public TemplateModel get(String key) throws TemplateModelException { - checkSessionExistence(); - return wrapper.wrap(session != null ? session.getAttribute(key) : null); - } - - private void checkSessionExistence() throws TemplateModelException { - if (session == null && request != null) { - session = request.getSession(false); - if (session != null && servlet != null) { - try { - servlet.initializeSessionAndInstallModel(request, response, - this, session); - } catch (RuntimeException e) { - throw e; - } catch (Exception e) { - throw new TemplateModelException(e); - } - } - } - } - - boolean isOrphaned(HttpSession currentSession) { - return (session != null && session != currentSession) || - (session == null && request == null); - } - - public boolean isEmpty() - throws TemplateModelException { - checkSessionExistence(); - return session == null || !session.getAttributeNames().hasMoreElements(); - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/ext/servlet/IncludePage.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/servlet/IncludePage.java b/src/main/java/freemarker/ext/servlet/IncludePage.java deleted file mode 100644 index 069fe74..0000000 --- a/src/main/java/freemarker/ext/servlet/IncludePage.java +++ /dev/null @@ -1,253 +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.servlet; - -import java.io.IOException; -import java.io.PrintWriter; -import java.io.Writer; -import java.lang.reflect.Array; -import java.util.Collection; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; - -import freemarker.core.Environment; -import freemarker.core._DelayedFTLTypeDescription; -import freemarker.core._MiscTemplateException; -import freemarker.template.TemplateBooleanModel; -import freemarker.template.TemplateDirectiveBody; -import freemarker.template.TemplateDirectiveModel; -import freemarker.template.TemplateException; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateScalarModel; -import freemarker.template.utility.DeepUnwrap; - - -/** - * A model that when invoked with a 'path' parameter will perform a servlet - * include. It also support an optional hash named 'params' which specifies - * request parameters for the include - its keys are strings, its values - * should be either strings or sequences of strings (for multiple valued - * parameters). A third optional parameter 'inherit_params' should be a boolean - * when specified, and it defaults to true when not specified. A value of true - * means that the include inherits the request parameters from the current - * request. In this case values in 'params' will get prepended to the existing - * values of parameters. - */ -public class IncludePage implements TemplateDirectiveModel { - private final HttpServletRequest request; - private final HttpServletResponse response; - - public IncludePage(HttpServletRequest request, HttpServletResponse response) { - this.request = request; - this.response = response; - } - - public void execute(final Environment env, Map params, - TemplateModel[] loopVars, TemplateDirectiveBody body) - throws TemplateException, IOException { - // Determine the path - final TemplateModel path = (TemplateModel) params.get("path"); - if (path == null) { - throw new _MiscTemplateException(env, "Missing required parameter \"path\""); - } - if (!(path instanceof TemplateScalarModel)) { - throw new _MiscTemplateException(env, - "Expected a scalar model. \"path\" is instead ", new _DelayedFTLTypeDescription(path)); - } - final String strPath = ((TemplateScalarModel) path).getAsString(); - if (strPath == null) { - throw new _MiscTemplateException(env, "String value of \"path\" parameter is null"); - } - - // See whether we need to use a custom response (if we're inside a TTM - // or TDM or macro nested body, we'll need to as then the current - // FM environment writer is not identical to HTTP servlet response - // writer. - final Writer envOut = env.getOut(); - final HttpServletResponse wrappedResponse; - if (envOut == response.getWriter()) { - // Don't bother wrapping if environment's writer is same as - // response writer - wrappedResponse = response; - } else { - final PrintWriter printWriter = (envOut instanceof PrintWriter) ? - (PrintWriter) envOut : - new PrintWriter(envOut); - // Otherwise, create a response wrapper that will pass the - // env writer, potentially first wrapping it in a print - // writer when it ain't one already. - wrappedResponse = new HttpServletResponseWrapper(response) { - @Override - public PrintWriter getWriter() { - return printWriter; - } - }; - } - - // Determine inherit_params value - final boolean inheritParams; - final TemplateModel inheritParamsModel = (TemplateModel) params.get("inherit_params"); - if (inheritParamsModel == null) { - // defaults to true when not specified - inheritParams = true; - } else { - if (!(inheritParamsModel instanceof TemplateBooleanModel)) { - throw new _MiscTemplateException(env, - "\"inherit_params\" should be a boolean but it's a(n) ", - inheritParamsModel.getClass().getName(), " instead"); - } - inheritParams = ((TemplateBooleanModel) inheritParamsModel).getAsBoolean(); - } - - // Get explicit params, if any - final TemplateModel paramsModel = (TemplateModel) params.get("params"); - - // Determine whether we need to wrap the request - final HttpServletRequest wrappedRequest; - if (paramsModel == null && inheritParams) { - // Inherit original request params & no params explicitly - // specified, so use the original request - wrappedRequest = request; - } else { - // In any other case, use a custom request wrapper - final Map paramsMap; - if (paramsModel != null) { - // Convert params to a Map - final Object unwrapped = DeepUnwrap.unwrap(paramsModel); - if (!(unwrapped instanceof Map)) { - throw new _MiscTemplateException(env, - "Expected \"params\" to unwrap into a java.util.Map. It unwrapped into ", - unwrapped.getClass().getName(), " instead."); - } - paramsMap = (Map) unwrapped; - } else { - paramsMap = Collections.EMPTY_MAP; - } - wrappedRequest = new CustomParamsRequest(request, paramsMap, - inheritParams); - } - - // Finally, do the include - try { - request.getRequestDispatcher(strPath).include(wrappedRequest, - wrappedResponse); - } catch (ServletException e) { - throw new _MiscTemplateException(e, env); - } - } - - private static final class CustomParamsRequest extends HttpServletRequestWrapper { - private final HashMap paramsMap; - - private CustomParamsRequest(HttpServletRequest request, Map paramMap, - boolean inheritParams) { - super(request); - paramsMap = inheritParams ? new HashMap(request.getParameterMap()) : new HashMap(); - for (Iterator it = paramMap.entrySet().iterator(); it.hasNext(); ) { - Map.Entry entry = (Map.Entry) it.next(); - String name = String.valueOf(entry.getKey()); - Object value = entry.getValue(); - final String[] valueArray; - if (value == null) { - // Null values are explicitly added (so, among other - // things, we can hide inherited param values). - valueArray = new String[] { null }; - } else if (value instanceof String[]) { - // String[] arrays are just passed through - valueArray = (String[]) value; - } else if (value instanceof Collection) { - // Collections are converted to String[], with - // String.valueOf() used on elements - Collection col = (Collection) value; - valueArray = new String[col.size()]; - int i = 0; - for (Iterator it2 = col.iterator(); it2.hasNext(); ) { - valueArray[i++] = String.valueOf(it2.next()); - } - } else if (value.getClass().isArray()) { - // Other array types are too converted to String[], with - // String.valueOf() used on elements - int len = Array.getLength(value); - valueArray = new String[len]; - for (int i = 0; i < len; ++i) { - valueArray[i] = String.valueOf(Array.get(value, i)); - } - } else { - // All other values (including strings) are converted to a - // single-element String[], with String.valueOf applied to - // the value. - valueArray = new String[] { String.valueOf(value) }; - } - String[] existingParams = (String[]) paramsMap.get(name); - int el = existingParams == null ? 0 : existingParams.length; - if (el == 0) { - // No original params, just put our array - paramsMap.put(name, valueArray); - } else { - int vl = valueArray.length; - if (vl > 0) { - // Both original params and new params, prepend our - // params to original params - String[] newValueArray = new String[el + vl]; - System.arraycopy(valueArray, 0, newValueArray, 0, vl); - System.arraycopy(existingParams, 0, newValueArray, vl, el); - paramsMap.put(name, newValueArray); - } - } - } - } - - @Override - public String[] getParameterValues(String name) { - String[] value = ((String[]) paramsMap.get(name)); - return value != null ? (String[]) value.clone() : null; - } - - @Override - public String getParameter(String name) { - String[] values = (String[]) paramsMap.get(name); - return values != null && values.length > 0 ? values[0] : null; - } - - @Override - public Enumeration getParameterNames() { - return Collections.enumeration(paramsMap.keySet()); - } - - @Override - public Map getParameterMap() { - HashMap clone = (HashMap) paramsMap.clone(); - for (Iterator it = clone.entrySet().iterator(); it.hasNext(); ) { - Map.Entry entry = (Map.Entry) it.next(); - entry.setValue(((String[]) entry.getValue()).clone()); - } - return Collections.unmodifiableMap(clone); - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/ext/servlet/InitParamParser.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/servlet/InitParamParser.java b/src/main/java/freemarker/ext/servlet/InitParamParser.java deleted file mode 100644 index feb5b98..0000000 --- a/src/main/java/freemarker/ext/servlet/InitParamParser.java +++ /dev/null @@ -1,268 +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.servlet; - -import java.io.File; -import java.io.IOException; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Pattern; - -import javax.servlet.ServletContext; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import freemarker.cache.ClassTemplateLoader; -import freemarker.cache.FileTemplateLoader; -import freemarker.cache.MultiTemplateLoader; -import freemarker.cache.TemplateLoader; -import freemarker.cache.WebAppTemplateLoader; -import freemarker.core._ObjectBuilderSettingEvaluator; -import freemarker.core._SettingEvaluationEnvironment; -import freemarker.template.Configuration; -import freemarker.template._TemplateAPI; -import freemarker.template.utility.StringUtil; - - -final class InitParamParser { - - static final String TEMPLATE_PATH_PREFIX_CLASS = "class://"; - static final String TEMPLATE_PATH_PREFIX_CLASSPATH = "classpath:"; - static final String TEMPLATE_PATH_PREFIX_FILE = "file://"; - static final String TEMPLATE_PATH_SETTINGS_BI_NAME = "settings"; - - private static final Logger LOG = LoggerFactory.getLogger("freemarker.servlet"); - - private InitParamParser() { - // Not to be instantiated - } - - static TemplateLoader createTemplateLoader( - String templatePath, Configuration cfg, Class classLoaderClass, ServletContext srvCtx) - throws IOException { - final int settingAssignmentsStart = findTemplatePathSettingAssignmentsStart(templatePath); - String pureTemplatePath = (settingAssignmentsStart == -1 ? templatePath : templatePath.substring(0, settingAssignmentsStart)) - .trim(); - - final TemplateLoader templateLoader; - if (pureTemplatePath.startsWith(TEMPLATE_PATH_PREFIX_CLASS)) { - String packagePath = pureTemplatePath.substring(TEMPLATE_PATH_PREFIX_CLASS.length()); - packagePath = normalizeToAbsolutePackagePath(packagePath); - templateLoader = new ClassTemplateLoader(classLoaderClass, packagePath); - } else if (pureTemplatePath.startsWith(TEMPLATE_PATH_PREFIX_CLASSPATH)) { - // To be similar to Spring resource paths, we don't require "//": - String packagePath = pureTemplatePath.substring(TEMPLATE_PATH_PREFIX_CLASSPATH.length()); - packagePath = normalizeToAbsolutePackagePath(packagePath); - - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - if (classLoader == null) { - LOG.warn("No Thread Context Class Loader was found. Falling back to the class loader of {}.", - classLoaderClass.getName()); - classLoader = classLoaderClass.getClassLoader(); - } - - templateLoader = new ClassTemplateLoader(classLoader, packagePath); - } else if (pureTemplatePath.startsWith(TEMPLATE_PATH_PREFIX_FILE)) { - String filePath = pureTemplatePath.substring(TEMPLATE_PATH_PREFIX_FILE.length()); - templateLoader = new FileTemplateLoader(new File(filePath)); - } else if (pureTemplatePath.startsWith("[") - && cfg.getIncompatibleImprovements().intValue() >= _TemplateAPI.VERSION_INT_2_3_22) { - if (!pureTemplatePath.endsWith("]")) { - // B.C. constraint: Can't throw any checked exceptions. - throw new TemplatePathParsingException("Failed to parse template path; closing \"]\" is missing."); - } - String commaSepItems = pureTemplatePath.substring(1, pureTemplatePath.length() - 1).trim(); - List listItems = parseCommaSeparatedTemplatePaths(commaSepItems); - TemplateLoader[] templateLoaders = new TemplateLoader[listItems.size()]; - for (int i = 0; i < listItems.size(); i++) { - String pathItem = (String) listItems.get(i); - templateLoaders[i] = createTemplateLoader(pathItem, cfg, classLoaderClass, srvCtx); - } - templateLoader = new MultiTemplateLoader(templateLoaders); - } else if (pureTemplatePath.startsWith("{") - && cfg.getIncompatibleImprovements().intValue() >= _TemplateAPI.VERSION_INT_2_3_22) { - throw new TemplatePathParsingException("Template paths starting with \"{\" are reseved for future purposes"); - } else { - templateLoader = new WebAppTemplateLoader(srvCtx, pureTemplatePath); - } - - if (settingAssignmentsStart != -1) { - try { - int nextPos = _ObjectBuilderSettingEvaluator.configureBean( - templatePath, templatePath.indexOf('(', settingAssignmentsStart) + 1, templateLoader, - _SettingEvaluationEnvironment.getCurrent()); - if (nextPos != templatePath.length()) { - throw new TemplatePathParsingException("Template path should end after the setting list in: " - + templatePath); - } - } catch (Exception e) { - throw new TemplatePathParsingException("Failed to set properties in: " + templatePath, e); - } - } - - return templateLoader; - } - - static String normalizeToAbsolutePackagePath(String path) { - while (path.startsWith("/")) { - path = path.substring(1); - } - return "/" + path; - } - - static List/*<String>*/ parseCommaSeparatedList(String value) throws ParseException { - List/*<String>*/ valuesList = new ArrayList(); - String[] values = StringUtil.split(value, ','); - for (int i = 0; i < values.length; i++) { - final String s = values[i].trim(); - if (s.length() != 0) { - valuesList.add(s); - } else if (i != values.length - 1) { - throw new ParseException("Missing list item berfore a comma", -1); - } - } - return valuesList; - } - - static List parseCommaSeparatedPatterns(String value) throws ParseException { - List/*<String>*/ values = parseCommaSeparatedList(value); - List/*<Pattern>*/ patterns = new ArrayList(values.size()); - for (int i = 0; i < values.size(); i++) { - patterns.add(Pattern.compile((String) values.get(i))); - } - return patterns; - } - - /** - * This is like {@link #parseCommaSeparatedList(String)}, but is not confused by commas inside - * {@code ?settings(...)} parts at the end of the items. - */ - static List parseCommaSeparatedTemplatePaths(String commaSepItems) { - List listItems; - listItems = new ArrayList(); - while (commaSepItems.length() != 0) { - int itemSettingAssignmentsStart = findTemplatePathSettingAssignmentsStart(commaSepItems); - int pureItemEnd = itemSettingAssignmentsStart != -1 ? itemSettingAssignmentsStart : commaSepItems.length(); - int prevComaIdx = commaSepItems.lastIndexOf(',', pureItemEnd - 1); - int itemStart = prevComaIdx != -1 ? prevComaIdx + 1 : 0; - final String item = commaSepItems.substring(itemStart).trim(); - if (item.length() != 0) { - listItems.add(0, item); - } else if (listItems.size() > 0) { - throw new TemplatePathParsingException("Missing list item before a comma"); - } - commaSepItems = prevComaIdx != -1 ? commaSepItems.substring(0, prevComaIdx).trim() : ""; - } - return listItems; - } - - /** - * @return -1 if there's no setting assignment. - */ - static int findTemplatePathSettingAssignmentsStart(String s) { - int pos = s.length() - 1; - - // Skip WS - while (pos >= 0 && Character.isWhitespace(s.charAt(pos))) { - pos--; - } - - // Skip `)` - if (pos < 0 || s.charAt(pos) != ')') return -1; - pos--; - - // Skip `(...` - int parLevel = 1; - int mode = 0; - while (parLevel > 0) { - if (pos < 0) return -1; - char c = s.charAt(pos); - switch (mode) { - case 0: // 0: outside string literal - switch (c) { - case '(': parLevel--; break; - case ')': parLevel++; break; - case '\'': mode = 1; break; - case '"': mode = 2; break; - } - break; - case 1: // 1: inside '...' - if (c == '\'' && !(pos > 0 && s.charAt(pos - 1) == '\\')) { - mode = 0; - } - break; - case 2: // 2: inside "..." - if (c == '"' && !(pos > 0 && s.charAt(pos - 1) == '\\')) { - mode = 0; - } - break; - } - pos--; - } - - // Skip WS - while (pos >= 0 && Character.isWhitespace(s.charAt(pos))) { - pos--; - } - - int biNameEnd = pos + 1; - - // Skip name chars - while (pos >= 0 && Character.isJavaIdentifierPart(s.charAt(pos))) { - pos--; - } - - int biNameStart = pos + 1; - if (biNameStart == biNameEnd) { - return -1; - } - String biName = s.substring(biNameStart, biNameEnd); - - // Skip WS - while (pos >= 0 && Character.isWhitespace(s.charAt(pos))) { - pos--; - } - - // Skip `?` - if (pos < 0 || s.charAt(pos) != '?') return -1; - - if (!biName.equals(TEMPLATE_PATH_SETTINGS_BI_NAME)) { - throw new TemplatePathParsingException( - StringUtil.jQuote(biName) + " is unexpected after the \"?\". " - + "Expected \"" + TEMPLATE_PATH_SETTINGS_BI_NAME + "\"."); - } - - return pos; - } - - private static final class TemplatePathParsingException extends RuntimeException { - - public TemplatePathParsingException(String message, Throwable cause) { - super(message, cause); - } - - public TemplatePathParsingException(String message) { - super(message); - } - - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/ext/servlet/ServletContextHashModel.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/servlet/ServletContextHashModel.java b/src/main/java/freemarker/ext/servlet/ServletContextHashModel.java deleted file mode 100644 index 2edb374..0000000 --- a/src/main/java/freemarker/ext/servlet/ServletContextHashModel.java +++ /dev/null @@ -1,72 +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.servlet; - -import javax.servlet.GenericServlet; -import javax.servlet.ServletContext; - -import freemarker.template.ObjectWrapper; -import freemarker.template.TemplateHashModel; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; - -/** - * TemplateHashModel wrapper for a ServletContext attributes. - */ -public final class ServletContextHashModel implements TemplateHashModel { - private final GenericServlet servlet; - private final ServletContext servletctx; - private final ObjectWrapper wrapper; - - public ServletContextHashModel( - GenericServlet servlet, ObjectWrapper wrapper) { - this.servlet = servlet; - this.servletctx = servlet.getServletContext(); - this.wrapper = wrapper; - } - - /** - * @deprecated use - * {@link #ServletContextHashModel(GenericServlet, ObjectWrapper)} instead. - */ - @Deprecated - public ServletContextHashModel( - ServletContext servletctx, ObjectWrapper wrapper) { - this.servlet = null; - this.servletctx = servletctx; - this.wrapper = wrapper; - } - - public TemplateModel get(String key) throws TemplateModelException { - return wrapper.wrap(servletctx.getAttribute(key)); - } - - public boolean isEmpty() { - return !servletctx.getAttributeNames().hasMoreElements(); - } - - /** - * Returns the underlying servlet. Can return null if this object was - * created using the deprecated constructor. - */ - public GenericServlet getServlet() { - return servlet; - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/ext/servlet/package.html ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/servlet/package.html b/src/main/java/freemarker/ext/servlet/package.html deleted file mode 100644 index 08f5267..0000000 --- a/src/main/java/freemarker/ext/servlet/package.html +++ /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. ---> -<html> -<body> -<p>Servlet for legacy "Model 2" frameworks that allows using FreeMarker -templates instead of JSP as the MVC View -(see <a href="http://freemarker.org/docs/pgui_misc_servlet.html" target="_blank">in the Manual</a>).</p> -</body> -</html> http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/ext/util/IdentityHashMap.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/util/IdentityHashMap.java b/src/main/java/freemarker/ext/util/IdentityHashMap.java deleted file mode 100644 index 13e140f..0000000 --- a/src/main/java/freemarker/ext/util/IdentityHashMap.java +++ /dev/null @@ -1,839 +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.util; - -import java.util.AbstractCollection; -import java.util.AbstractMap; -import java.util.AbstractSet; -import java.util.Collection; -import java.util.ConcurrentModificationException; -import java.util.Iterator; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.Set; - -/** - * Was used instead of {@link java.util.IdentityHashMap} before that was added to Java itself in Java 1.4. - * - * @deprecated Use {@link java.util.IdentityHashMap} instead. - */ -@SuppressWarnings("rawtypes") -@Deprecated -public class IdentityHashMap - extends AbstractMap - implements Map, Cloneable, java.io.Serializable { - - public static final long serialVersionUID = 362498820763181265L; - /** - * The hash table data. - */ - private transient Entry table[]; - - /** - * The total number of mappings in the hash table. - */ - private transient int count; - - /** - * The table is rehashed when its size exceeds this threshold. (The - * value of this field is (int)(capacity * loadFactor).) - */ - private int threshold; - - /** - * The load factor for the hashtable. - */ - private float loadFactor; - - /** - * The number of times this IdentityHashMap has been structurally modified - * Structural modifications are those that change the number of mappings in - * the IdentityHashMap or otherwise modify its internal structure (e.g., - * rehash). This field is used to make iterators on Collection-views of - * the IdentityHashMap fail-fast. (See ConcurrentModificationException). - */ - private transient int modCount = 0; - - /** - * Constructs a new, empty map with the specified initial - * capacity and the specified load factor. - * - * @param initialCapacity the initial capacity of the IdentityHashMap. - * @param loadFactor the load factor of the IdentityHashMap - * @throws IllegalArgumentException if the initial capacity is less - * than zero, or if the load factor is nonpositive. - */ - public IdentityHashMap(int initialCapacity, float loadFactor) { - if (initialCapacity < 0) - throw new IllegalArgumentException( - "Illegal Initial Capacity: " + initialCapacity); - if (loadFactor <= 0 || Float.isNaN(loadFactor)) - throw new IllegalArgumentException( - "Illegal Load factor: " + loadFactor); - if (initialCapacity == 0) - initialCapacity = 1; - this.loadFactor = loadFactor; - table = new Entry[initialCapacity]; - threshold = (int) (initialCapacity * loadFactor); - } - - /** - * Constructs a new, empty map with the specified initial capacity - * and default load factor, which is <tt>0.75</tt>. - * - * @param initialCapacity the initial capacity of the IdentityHashMap. - * @throws IllegalArgumentException if the initial capacity is less - * than zero. - */ - public IdentityHashMap(int initialCapacity) { - this(initialCapacity, 0.75f); - } - - /** - * Constructs a new, empty map with a default capacity and load - * factor, which is <tt>0.75</tt>. - */ - public IdentityHashMap() { - this(11, 0.75f); - } - - /** - * Constructs a new map with the same mappings as the given map. The - * map is created with a capacity of twice the number of mappings in - * the given map or 11 (whichever is greater), and a default load factor, - * which is <tt>0.75</tt>. - * - * @param t the map whose mappings are to be placed in this map. - */ - public IdentityHashMap(Map t) { - this(Math.max(2 * t.size(), 11), 0.75f); - putAll(t); - } - - /** - * Returns the number of key-value mappings in this map. - * - * @return the number of key-value mappings in this map. - */ - @Override - public int size() { - return count; - } - - /** - * Returns <tt>true</tt> if this map contains no key-value mappings. - * - * @return <tt>true</tt> if this map contains no key-value mappings. - */ - @Override - public boolean isEmpty() { - return count == 0; - } - - /** - * Returns <tt>true</tt> if this map maps one or more keys to the - * specified value. - * - * @param value value whose presence in this map is to be tested. - * @return <tt>true</tt> if this map maps one or more keys to the - * specified value. - */ - @Override - public boolean containsValue(Object value) { - Entry tab[] = table; - - if (value == null) { - for (int i = tab.length; i-- > 0; ) - for (Entry e = tab[i]; e != null; e = e.next) - if (e.value == null) - return true; - } else { - for (int i = tab.length; i-- > 0; ) - for (Entry e = tab[i]; e != null; e = e.next) - if (value.equals(e.value)) - return true; - } - - return false; - } - - /** - * Returns <tt>true</tt> if this map contains a mapping for the specified - * key. - * - * @return <tt>true</tt> if this map contains a mapping for the specified - * key. - * @param key key whose presence in this Map is to be tested. - */ - @Override - public boolean containsKey(Object key) { - Entry tab[] = table; - if (key != null) { - int hash = System.identityHashCode(key); - int index = (hash & 0x7FFFFFFF) % tab.length; - for (Entry e = tab[index]; e != null; e = e.next) - if (e.hash == hash && key == e.key) - return true; - } else { - for (Entry e = tab[0]; e != null; e = e.next) - if (e.key == null) - return true; - } - - return false; - } - - /** - * Returns the value to which this map maps the specified key. Returns - * <tt>null</tt> if the map contains no mapping for this key. A return - * value of <tt>null</tt> does not <i>necessarily</i> indicate that the - * map contains no mapping for the key; it's also possible that the map - * explicitly maps the key to <tt>null</tt>. The <tt>containsKey</tt> - * operation may be used to distinguish these two cases. - * - * @return the value to which this map maps the specified key. - * @param key key whose associated value is to be returned. - */ - @Override - public Object get(Object key) { - Entry tab[] = table; - - if (key != null) { - int hash = System.identityHashCode(key); - int index = (hash & 0x7FFFFFFF) % tab.length; - for (Entry e = tab[index]; e != null; e = e.next) - if ((e.hash == hash) && key == e.key) - return e.value; - } else { - for (Entry e = tab[0]; e != null; e = e.next) - if (e.key == null) - return e.value; - } - - return null; - } - - /** - * Rehashes the contents of this map into a new <tt>IdentityHashMap</tt> instance - * with a larger capacity. This method is called automatically when the - * number of keys in this map exceeds its capacity and load factor. - */ - private void rehash() { - int oldCapacity = table.length; - Entry oldMap[] = table; - - int newCapacity = oldCapacity * 2 + 1; - Entry newMap[] = new Entry[newCapacity]; - - modCount++; - threshold = (int) (newCapacity * loadFactor); - table = newMap; - - for (int i = oldCapacity; i-- > 0; ) { - for (Entry old = oldMap[i]; old != null; ) { - Entry e = old; - old = old.next; - - int index = (e.hash & 0x7FFFFFFF) % newCapacity; - e.next = newMap[index]; - newMap[index] = e; - } - } - } - - /** - * Associates the specified value with the specified key in this map. - * If the map previously contained a mapping for this key, the old - * value is replaced. - * - * @param key key with which the specified value is to be associated. - * @param value value to be associated with the specified key. - * @return previous value associated with specified key, or <tt>null</tt> - * if there was no mapping for key. A <tt>null</tt> return can - * also indicate that the IdentityHashMap previously associated - * <tt>null</tt> with the specified key. - */ - @Override - public Object put(Object key, Object value) { - // Makes sure the key is not already in the IdentityHashMap. - Entry tab[] = table; - int hash = 0; - int index = 0; - - if (key != null) { - hash = System.identityHashCode(key); - index = (hash & 0x7FFFFFFF) % tab.length; - for (Entry e = tab[index]; e != null; e = e.next) { - if ((e.hash == hash) && key == e.key) { - Object old = e.value; - e.value = value; - return old; - } - } - } else { - for (Entry e = tab[0]; e != null; e = e.next) { - if (e.key == null) { - Object old = e.value; - e.value = value; - return old; - } - } - } - - modCount++; - if (count >= threshold) { - // Rehash the table if the threshold is exceeded - rehash(); - - tab = table; - index = (hash & 0x7FFFFFFF) % tab.length; - } - - // Creates the new entry. - Entry e = new Entry(hash, key, value, tab[index]); - tab[index] = e; - count++; - return null; - } - - /** - * Removes the mapping for this key from this map if present. - * - * @param key key whose mapping is to be removed from the map. - * @return previous value associated with specified key, or <tt>null</tt> - * if there was no mapping for key. A <tt>null</tt> return can - * also indicate that the map previously associated <tt>null</tt> - * with the specified key. - */ - @Override - public Object remove(Object key) { - Entry tab[] = table; - - if (key != null) { - int hash = System.identityHashCode(key); - int index = (hash & 0x7FFFFFFF) % tab.length; - - for (Entry e = tab[index], prev = null; - e != null; - prev = e, e = e.next) { - if ((e.hash == hash) && key == e.key) { - modCount++; - if (prev != null) - prev.next = e.next; - else - tab[index] = e.next; - - count--; - Object oldValue = e.value; - e.value = null; - return oldValue; - } - } - } else { - for (Entry e = tab[0], prev = null; - e != null; - prev = e, e = e.next) { - if (e.key == null) { - modCount++; - if (prev != null) - prev.next = e.next; - else - tab[0] = e.next; - - count--; - Object oldValue = e.value; - e.value = null; - return oldValue; - } - } - } - - return null; - } - - /** - * Copies all of the mappings from the specified map to this one. - * - * These mappings replace any mappings that this map had for any of the - * keys currently in the specified Map. - * - * @param t Mappings to be stored in this map. - */ - @Override - public void putAll(Map t) { - Iterator i = t.entrySet().iterator(); - while (i.hasNext()) { - Map.Entry e = (Map.Entry) i.next(); - put(e.getKey(), e.getValue()); - } - } - - /** - * Removes all mappings from this map. - */ - @Override - public void clear() { - Entry tab[] = table; - modCount++; - for (int index = tab.length; --index >= 0; ) - tab[index] = null; - count = 0; - } - - /** - * Returns a shallow copy of this <tt>IdentityHashMap</tt> instance: the keys and - * values themselves are not cloned. - * - * @return a shallow copy of this map. - */ - @Override - public Object clone() { - try { - IdentityHashMap t = (IdentityHashMap) super.clone(); - t.table = new Entry[table.length]; - for (int i = table.length; i-- > 0; ) { - t.table[i] = - (table[i] != null) ? (Entry) table[i].clone() : null; - } - t.keySet = null; - t.entrySet = null; - t.values = null; - t.modCount = 0; - return t; - } catch (CloneNotSupportedException e) { - // this shouldn't happen, since we are Cloneable - throw new InternalError(); - } - } - - // Views - - private transient Set keySet = null; - private transient Set entrySet = null; - private transient Collection values = null; - - /** - * Returns a set view of the keys contained in this map. The set is - * backed by the map, so changes to the map are reflected in the set, and - * vice versa. The set supports element removal, which removes the - * corresponding mapping from this map, via the <tt>Iterator.remove</tt>, - * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt>, and - * <tt>clear</tt> operations. It does not support the <tt>add</tt> or - * <tt>addAll</tt> operations. - * - * @return a set view of the keys contained in this map. - */ - @Override - public Set keySet() { - if (keySet == null) { - keySet = new AbstractSet() - { - @Override - public Iterator iterator() { - return getHashIterator(KEYS); - } - @Override - public int size() { - return count; - } - @Override - public boolean contains(Object o) { - return containsKey(o); - } - @Override - public boolean remove(Object o) { - int oldSize = count; - IdentityHashMap.this.remove(o); - return count != oldSize; - } - @Override - public void clear() { - IdentityHashMap.this.clear(); - } - }; - } - return keySet; - } - - /** - * Returns a collection view of the values contained in this map. The - * collection is backed by the map, so changes to the map are reflected in - * the collection, and vice versa. The collection supports element - * removal, which removes the corresponding mapping from this map, via the - * <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>, - * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations. - * It does not support the <tt>add</tt> or <tt>addAll</tt> operations. - * - * @return a collection view of the values contained in this map. - */ - @Override - public Collection values() { - if (values == null) { - values = new AbstractCollection() - { - @Override - public Iterator iterator() { - return getHashIterator(VALUES); - } - @Override - public int size() { - return count; - } - @Override - public boolean contains(Object o) { - return containsValue(o); - } - @Override - public void clear() { - IdentityHashMap.this.clear(); - } - }; - } - return values; - } - - /** - * Returns a collection view of the mappings contained in this map. Each - * element in the returned collection is a <tt>Map.Entry</tt>. The - * collection is backed by the map, so changes to the map are reflected in - * the collection, and vice versa. The collection supports element - * removal, which removes the corresponding mapping from the map, via the - * <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>, - * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations. - * It does not support the <tt>add</tt> or <tt>addAll</tt> operations. - * - * @return a collection view of the mappings contained in this map. - * @see java.util.Map.Entry - */ - @Override - public Set entrySet() { - if (entrySet == null) { - entrySet = new AbstractSet() - { - @Override - public Iterator iterator() { - return getHashIterator(ENTRIES); - } - - @Override - public boolean contains(Object o) { - if (!(o instanceof Map.Entry)) - return false; - Map.Entry entry = (Map.Entry) o; - Object key = entry.getKey(); - Entry tab[] = table; - int hash = (key == null ? 0 : System.identityHashCode(key)); - int index = (hash & 0x7FFFFFFF) % tab.length; - - for (Entry e = tab[index]; e != null; e = e.next) - if (e.hash == hash && e.equals(entry)) - return true; - return false; - } - - @Override - public boolean remove(Object o) { - if (!(o instanceof Map.Entry)) - return false; - Map.Entry entry = (Map.Entry) o; - Object key = entry.getKey(); - Entry tab[] = table; - int hash = (key == null ? 0 : System.identityHashCode(key)); - int index = (hash & 0x7FFFFFFF) % tab.length; - - for (Entry e = tab[index], prev = null; - e != null; - prev = e, e = e.next) { - if (e.hash == hash && e.equals(entry)) { - modCount++; - if (prev != null) - prev.next = e.next; - else - tab[index] = e.next; - - count--; - e.value = null; - return true; - } - } - return false; - } - - @Override - public int size() { - return count; - } - - @Override - public void clear() { - IdentityHashMap.this.clear(); - } - }; - } - - return entrySet; - } - - private Iterator getHashIterator(int type) { - if (count == 0) { - return emptyHashIterator; - } else { - return new HashIterator(type); - } - } - - /** - * IdentityHashMap collision list entry. - */ - private static class Entry implements Map.Entry { - int hash; - Object key; - Object value; - Entry next; - - Entry(int hash, Object key, Object value, Entry next) { - this.hash = hash; - this.key = key; - this.value = value; - this.next = next; - } - - @Override - protected Object clone() { - return new Entry( - hash, - key, - value, - (next == null ? null : (Entry) next.clone())); - } - - // Map.Entry Ops - - public Object getKey() { - return key; - } - - public Object getValue() { - return value; - } - - public Object setValue(Object value) { - Object oldValue = this.value; - this.value = value; - return oldValue; - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof Map.Entry)) - return false; - Map.Entry e = (Map.Entry) o; - - return (key == e.getKey()) - && (value == null - ? e.getValue() == null - : value.equals(e.getValue())); - } - - @Override - public int hashCode() { - return hash ^ (value == null ? 0 : value.hashCode()); - } - - @Override - public String toString() { - return key + "=" + value; - } - } - - // Types of Iterators - private static final int KEYS = 0; - private static final int VALUES = 1; - private static final int ENTRIES = 2; - - private static EmptyHashIterator emptyHashIterator = - new EmptyHashIterator(); - - private static class EmptyHashIterator implements Iterator { - - EmptyHashIterator() { - - } - - public boolean hasNext() { - return false; - } - - public Object next() { - throw new NoSuchElementException(); - } - - public void remove() { - throw new IllegalStateException(); - } - - } - - private class HashIterator implements Iterator { - Entry[] table = IdentityHashMap.this.table; - int index = table.length; - Entry entry = null; - Entry lastReturned = null; - int type; - - /** - * The modCount value that the iterator believes that the backing - * List should have. If this expectation is violated, the iterator - * has detected concurrent modification. - */ - private int expectedModCount = modCount; - - HashIterator(int type) { - this.type = type; - } - - public boolean hasNext() { - Entry e = entry; - int i = index; - Entry t[] = table; - /* Use locals for faster loop iteration */ - while (e == null && i > 0) - e = t[--i]; - entry = e; - index = i; - return e != null; - } - - public Object next() { - if (modCount != expectedModCount) - throw new ConcurrentModificationException(); - - Entry et = entry; - int i = index; - Entry t[] = table; - - /* Use locals for faster loop iteration */ - while (et == null && i > 0) - et = t[--i]; - - entry = et; - index = i; - if (et != null) { - Entry e = lastReturned = entry; - entry = e.next; - return type == KEYS ? e.key : (type == VALUES ? e.value : e); - } - throw new NoSuchElementException(); - } - - public void remove() { - if (lastReturned == null) - throw new IllegalStateException(); - if (modCount != expectedModCount) - throw new ConcurrentModificationException(); - - Entry[] tab = IdentityHashMap.this.table; - int index = (lastReturned.hash & 0x7FFFFFFF) % tab.length; - - for (Entry e = tab[index], prev = null; - e != null; - prev = e, e = e.next) { - if (e == lastReturned) { - modCount++; - expectedModCount++; - if (prev == null) - tab[index] = e.next; - else - prev.next = e.next; - count--; - lastReturned = null; - return; - } - } - throw new ConcurrentModificationException(); - } - } - - /** - * Save the state of the <tt>IdentityHashMap</tt> instance to a stream (i.e., - * serialize it). - * - * @serialData The <i>capacity</i> of the IdentityHashMap (the length of the - * bucket array) is emitted (int), followed by the - * <i>size</i> of the IdentityHashMap (the number of key-value - * mappings), followed by the key (Object) and value (Object) - * for each key-value mapping represented by the IdentityHashMap - * The key-value mappings are emitted in no particular order. - */ - private void writeObject(java.io.ObjectOutputStream s) - throws java.io.IOException { - // Write out the threshold, loadfactor, and any hidden stuff - s.defaultWriteObject(); - - // Write out number of buckets - s.writeInt(table.length); - - // Write out size (number of Mappings) - s.writeInt(count); - - // Write out keys and values (alternating) - for (int index = table.length - 1; index >= 0; index--) { - Entry entry = table[index]; - - while (entry != null) { - s.writeObject(entry.key); - s.writeObject(entry.value); - entry = entry.next; - } - } - } - - /** - * Reconstitute the <tt>IdentityHashMap</tt> instance from a stream (i.e., - * deserialize it). - */ - private void readObject(java.io.ObjectInputStream s) - throws java.io.IOException, ClassNotFoundException { - // Read in the threshold, loadfactor, and any hidden stuff - s.defaultReadObject(); - - // Read in number of buckets and allocate the bucket array; - int numBuckets = s.readInt(); - table = new Entry[numBuckets]; - - // Read in size (number of Mappings) - int size = s.readInt(); - - // Read the keys and values, and put the mappings in the IdentityHashMap - for (int i = 0; i < size; i++) { - Object key = s.readObject(); - Object value = s.readObject(); - put(key, value); - } - } - - int capacity() { - return table.length; - } - - float loadFactor() { - return loadFactor; - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/ext/util/ModelCache.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/util/ModelCache.java b/src/main/java/freemarker/ext/util/ModelCache.java deleted file mode 100644 index db07691..0000000 --- a/src/main/java/freemarker/ext/util/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 freemarker.ext.util; - -import java.lang.ref.ReferenceQueue; -import java.lang.ref.SoftReference; -import java.util.IdentityHashMap; -import java.util.Map; - -import freemarker.template.TemplateModel; -import freemarker.template.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<Object, ModelReference>(); - refQueue = new ReferenceQueue<TemplateModel>(); - } 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 final 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 final 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 (TemplateModel) this.get(); - } - } - -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/ext/util/ModelFactory.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/util/ModelFactory.java b/src/main/java/freemarker/ext/util/ModelFactory.java deleted file mode 100644 index 18356c6..0000000 --- a/src/main/java/freemarker/ext/util/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 freemarker.ext.util; - -import freemarker.template.ObjectWrapper; -import freemarker.template.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/ecb4e230/src/main/java/freemarker/ext/util/WrapperTemplateModel.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/util/WrapperTemplateModel.java b/src/main/java/freemarker/ext/util/WrapperTemplateModel.java deleted file mode 100644 index 9265489..0000000 --- a/src/main/java/freemarker/ext/util/WrapperTemplateModel.java +++ /dev/null @@ -1,35 +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.util; - -import freemarker.template.TemplateModel; - -/** - * A generic interface for template models that wrap some underlying - * object, and wish to provide access to that wrapped object. - * - * <p>You may also want to implement {@link freemarker.template.AdapterTemplateModel}. - */ -public interface WrapperTemplateModel extends TemplateModel { - /** - * Retrieves the original object wrapped by this model. - */ - public Object getWrappedObject(); -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/ext/util/package.html ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/util/package.html b/src/main/java/freemarker/ext/util/package.html deleted file mode 100644 index 31c6092..0000000 --- a/src/main/java/freemarker/ext/util/package.html +++ /dev/null @@ -1,23 +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. ---> -<html> -<body> -<p>Various classes used by {@code freemarker.ext} but might be useful outside it too.</p> -</body> -</html> http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/template/AdapterTemplateModel.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/template/AdapterTemplateModel.java b/src/main/java/freemarker/template/AdapterTemplateModel.java deleted file mode 100644 index 2f32cae..0000000 --- a/src/main/java/freemarker/template/AdapterTemplateModel.java +++ /dev/null @@ -1,49 +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.template; - -/** - * A {@link TemplateModel} that can be unwrapped and then it considers a provided desired (hint) class. This is - * useful when multiple languages has to communicate with each other through FreeMarker. For example, if we have a - * model that wraps a Jython object, then we have to unwrap that differently when we pass it to plain Java method and - * when we pass it to a Jython method. - * - * <p>This is rarely implemented by applications. It is typically implemented by the model classes belonging to - * {@link ObjectWrapper}-s. - */ -public interface AdapterTemplateModel extends TemplateModel { - /** - * Retrieves the underlying object, or some other object semantically - * equivalent to its value narrowed by the class hint. - * @param hint the desired class of the returned value. An implementation - * should make reasonable effort to retrieve an object of the requested - * class, but if that is impossible, it must at least return the underlying - * object as-is. As a minimal requirement, an implementation must always - * return the exact underlying object when - * <tt>hint.isInstance(underlyingObject)</tt> holds. When called - * with <tt>java.lang.Object.class</tt>, it should return a generic Java - * object (i.e. if the model is wrapping a scripting language object that is - * further wrapping a Java object, the deepest underlying Java object should - * be returned). - * @return the underlying object, or its value accommodated for the hint - * class. - */ - public Object getAdaptedObject(Class<?> hint); -}
