/* * Copyright (C) 2011 eXo Platform SAS. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.exoplatform.web.controller.router; import java.util.HashMap; import java.util.Map; import org.exoplatform.web.controller.QualifiedName; /** * The render context used to compute the rendering of a parameter map. * * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> */ public class RenderContext { class Parameter { /** . */ private String value; /** . */ private final int index; /** This value is valid only if the parameter is matched. */ private String match; private Parameter(String value, int index) { this.value = value; this.index = index; } public String getValue() { return value; } public String getMatch() { return isMatched() ? match : null; } public boolean isMatched() { return stack.getDepth() > 0 && stack.get(index); } public void remove(String match) { if (stack.getDepth() < 1) { throw new IllegalStateException(); } if (stack.get(index)) { throw new AssertionError("We should not do that twice, shouldn't we ?"); } stack.set(index); this.match = match; } } /** . */ private final Map<QualifiedName, Parameter> parameters; /** . */ private BitStack stack = new BitStack(); /** . */ Regex.Matcher[] matchers; public RenderContext(Map<QualifiedName, String> map) { this(); // reset(map); } public RenderContext() { this.parameters = new HashMap<QualifiedName, Parameter>(); this.stack = new BitStack(); this.matchers = null; } Regex.Matcher matcher(Regex regex) { Regex.Matcher matcher = matchers[regex.index]; if (matcher == null) { matcher = matchers[regex.index] = regex.matcher(); } return matcher; } /** * Reuse the context with new parameters. * * @param map the map */ public void reset(Map<QualifiedName, String> map) { this.parameters.clear(); this.stack.reset(); // for (Map.Entry<QualifiedName, String> entry : map.entrySet()) { addParameter(entry.getKey(), entry.getValue()); } } void addParameter(QualifiedName name, String value) { if (stack.getDepth() > 0) { throw new IllegalStateException(); } if (name == null) { throw new NullPointerException(); } if (value == null) { throw new NullPointerException(); } Parameter parameter = parameters.get(name); if (parameter == null) { parameter = new Parameter(value, parameters.size()); parameters.put(name, parameter); } else { parameter.value = value; } } Parameter getParameter(QualifiedName name) { return parameters.get(name); } Iterable<QualifiedName> getNames() { return parameters.keySet(); } boolean isEmpty() { return stack.getDepth() == 0 || stack.isEmpty(); } void enter() { if (stack.getDepth() == 0) { stack.init(parameters.size()); } stack.push(); } void leave() { stack.pop(); } }