All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gwtplatform.mvp.client.proxy.ParameterTokenFormatter Maven / Gradle / Ivy

There is a newer version: 1.6
Show newest version
/**
 * Copyright 2010 ArcBees Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package com.gwtplatform.mvp.client.proxy;

import com.google.inject.Inject;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * Formats tokens from {@code String} values to {@link PlaceRequest} and
 * {@link PlaceRequest} hierarchies and vice-versa. The default implementation
 * uses:
 * 
    *
  • {@code '/'} to separate {@link PlaceRequest}s in a hierarchy;
  • *
  • {@code ';'} to separate parameters in a {@link PlaceRequest};
  • *
  • {@code '='} to separate the parameter name from its value.
  • *
* These symbols cannot be used in a name token. If one of the separating symbol * is encountered in a parameter or a value it is escaped by being duplicated. *

* For example, {@link ParameterTokenFormatter} would parse: * *

 * nameToken1;param1.1=value1.1;param1.2=value1.2/nameToken2/nameToken3;param3.1=value//3==1
 * 
* Into the following hierarchy of {@link PlaceRequest}: * *
 * { 
 *   { "nameToken1", { {"param1.1", "value1.1"}, {"parame1.2","value1.2"} },
 *     "nameToken2", {},
 *     "nameToken3", { {"param3.1", "value/3=1"} } }
 * }
 * 
* If you want to use different symbols as separator, use the * {@link #ParameterTokenFormatter(String, String, String)} constructor. * * @author Philippe Beaudoin */ public final class ParameterTokenFormatter implements TokenFormatter { protected static final String DEFAULT_HIERARCHY_SEPARATOR = "/"; protected static final String DEFAULT_PARAM_SEPARATOR = ";"; protected static final String DEFAULT_VALUE_SEPARATOR = "="; private final String hierarchyEscape; private final String hierarchyPattern; private final String hierarchySeparator; private final String paramEscape; private final String paramPattern; private final String paramSeparator; private final String valueEscape; private final String valuePattern; private final String valueSeparator; /** * Builds a {@link ParameterTokenFormatter} using the default separators. */ @Inject public ParameterTokenFormatter() { this(DEFAULT_HIERARCHY_SEPARATOR, DEFAULT_PARAM_SEPARATOR, DEFAULT_VALUE_SEPARATOR); } /** * This constructor makes it possible to use custom separators in your token * formatter. The separators must be 1-letter strings and they must all be * different from one another. * * @param hierarchySeparator The symbol used to separate {@link PlaceRequest} * in a hierarchy. Must be a 1-character string. * @param paramSeparator The symbol used to separate parameters in a * {@link PlaceRequest}. Must be a 1-character string. * @param valueSeparator The symbol used to separate the parameter name from * its value. Must be a 1-character string. */ public ParameterTokenFormatter(String hierarchySeparator, String paramSeparator, String valueSeparator) { assert hierarchySeparator.length() == 1; assert paramSeparator.length() == 1; assert valueSeparator.length() == 1; assert !hierarchySeparator.equals(paramSeparator); assert !hierarchySeparator.equals(valueSeparator); assert !paramSeparator.equals(valueSeparator); this.hierarchySeparator = hierarchySeparator; this.paramSeparator = paramSeparator; this.valueSeparator = valueSeparator; hierarchyPattern = hierarchySeparator + "(?!" + hierarchySeparator + ")"; hierarchyEscape = hierarchySeparator + hierarchySeparator; paramPattern = paramSeparator + "(?!" + paramSeparator + ")"; paramEscape = paramSeparator + paramSeparator; valuePattern = valueSeparator + "(?!" + valueSeparator + ")"; valueEscape = valueSeparator + valueSeparator; } @Override public String toHistoryToken(List placeRequestHierarchy) throws TokenFormatException { StringBuilder out = new StringBuilder(); for (int i = 0; i < placeRequestHierarchy.size(); ++i) { if (i != 0) { out.append(hierarchySeparator); } out.append(toPlaceToken(placeRequestHierarchy.get(i))); } return out.toString(); } @Override public PlaceRequest toPlaceRequest(String placeToken) throws TokenFormatException { PlaceRequest req = null; int split = placeToken.indexOf(paramSeparator); if (split == 0) { throw new TokenFormatException("Place history token is missing."); } else if (split == -1) { req = new PlaceRequest(placeToken); } else if (split >= 0) { req = new PlaceRequest(placeToken.substring(0, split)); String paramsChunk = placeToken.substring(split + 1); String[] paramTokens = paramsChunk.split(paramPattern); String completeParamToken = ""; for (String paramToken : paramTokens) { completeParamToken = completeParamToken + paramToken; // Will end with a separator if we had an escaped separator if (completeParamToken.endsWith(paramSeparator)) { continue; } String[] param = completeParamToken.split(valuePattern); completeParamToken = ""; String key = ""; int i = 0; for (; i < param.length; ++i) { key = key + param[i]; // Will end with a separator if we had an escaped separator if (!key.endsWith(valueSeparator)) { break; } } ++i; String value = ""; for (; i < param.length; ++i) { value = value + param[i]; // Will end with a separator if we had an escaped separator if (!value.endsWith(valueSeparator)) { break; } } ++i; if (i != param.length) { throw new TokenFormatException( "Bad parameter: Parameters require a single '" + valueSeparator + "' between the key and value."); } req = req.with(key, value); } } return req; } @Override public List toPlaceRequestHierarchy(String historyToken) throws TokenFormatException { List placeTokens = toPlaceTokenList(historyToken); List result = new ArrayList(); for (String placeToken : placeTokens) { result.add(toPlaceRequest(placeToken)); } return result; } @Override public String toPlaceToken(PlaceRequest placeRequest) { StringBuilder out = new StringBuilder(); out.append(placeRequest.getNameToken()); Set params = placeRequest.getParameterNames(); if (params != null && params.size() > 0) { for (String name : params) { out.append(paramSeparator); out.append(escape(name)).append(valueSeparator).append( escape(placeRequest.getParameter(name, null))); } } return out.toString(); } private String escape(String value) { return value.replaceAll(hierarchySeparator, hierarchyEscape).replaceAll( paramSeparator, paramEscape).replaceAll(valueSeparator, valueEscape); } private List toPlaceTokenList(String historyToken) throws TokenFormatException { String[] placeTokens = historyToken.split(hierarchyPattern); List result = new ArrayList(); String completePlaceToken = ""; for (String placeToken : placeTokens) { completePlaceToken = completePlaceToken + placeToken; // Will end with a separator if we had an escaped separator if (completePlaceToken.endsWith(hierarchySeparator)) { continue; } result.add(completePlaceToken); completePlaceToken = ""; } return result; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy