package org.tessell.place; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; import org.tessell.place.events.PlaceRequestEvent; import org.tessell.util.ObjectUtils; /** * This class represents a 'request' for a place location. It includes the 'id' of the place as well as any parameter * values. It can convert from and to String tokens for use with the GWT History. * <p/> * <p/> * Place request tokens are formatted like this: * <p/> * <code>#id(;key=value)*</code> * <p/> * <p/> * There is a mandatory 'id' value, followed by 0 or more key/value pairs, separated by semi-colons (';'). A few * examples follow: * <p/> * <ul> * <li> <code>#users</code></li> * <li> <code>#user;name=j.blogs</code></li> * <li> <code>#user-email;name=j.blogs;type=home</code></li> * </ul> * * @author David Peterson */ public class PlaceRequest { private final String name; private final LinkedHashMap<String, String> params = new LinkedHashMap<String, String>(); public PlaceRequest(final String name) { this.name = name; } protected PlaceRequest(final PlaceRequest req) { name = req.name; params.putAll(req.params); } protected PlaceRequest(final PlaceRequest req, final String name, final String value) { this.name = req.name; params.putAll(req.params); params.put(name, value); } public String getName() { return name; } public Set<String> getParameterNames() { return params.keySet(); } public String getParameter(final String key, final String defaultValue) { final String value = params.get(key); if (value == null || "".equals(value)) { return defaultValue; } return value; } /** * Returns a new instance of the request with the specified parameter name and value. If a parameter with the same * name was previously specified, the new request contains the new value. * * @param name * The new parameter name. * @param value * The new parameter value. * @return The new place request instance. */ public PlaceRequest with(final String name, final Object value) { return new PlaceRequest(this, name, ObjectUtils.toStr(value, "")); } /** @return a new {@link PlaceRequestEvent} for this {@link PlaceRequest}. */ public PlaceRequestEvent asEvent() { return new PlaceRequestEvent(this); } @Override public boolean equals(final Object object) { if (!(object instanceof PlaceRequest)) { return false; } final PlaceRequest other = (PlaceRequest) object; return other.name.equals(name) && other.params.equals(params); } @Override public int hashCode() { int result = 23; result = (result * 37) + name.hashCode(); result = (result * 37) + params.hashCode(); return result; } @Override public String toString() { final StringBuilder out = new StringBuilder(); out.append(name); if (params.size() > 0) { out.append(";"); // This is for debug view only, so don't do url encoding for (final Map.Entry<String, String> entry : params.entrySet()) { out.append(entry.getKey()).append("=").append(entry.getValue()).append(";"); } out.deleteCharAt(out.length() - 1); } return out.toString(); } }