You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by iv...@apache.org on 2009/10/11 02:02:29 UTC
svn commit: r823984 [6/11] - in /wicket/trunk: ./
wicket/src/main/java/org/apache/wicket/ng/
wicket/src/main/java/org/apache/wicket/ng/application/
wicket/src/main/java/org/apache/wicket/ng/behavior/
wicket/src/main/java/org/apache/wicket/ng/markup/ wi...
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/PageInstanceMapper.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/PageInstanceMapper.java?rev=823984&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/PageInstanceMapper.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/PageInstanceMapper.java Sun Oct 11 00:02:25 2009
@@ -0,0 +1,138 @@
+/*
+ * 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 org.apache.wicket.ng.request.mapper;
+
+import org.apache.wicket.ng.request.Request;
+import org.apache.wicket.ng.request.RequestHandler;
+import org.apache.wicket.ng.request.Url;
+import org.apache.wicket.ng.request.component.RequestablePage;
+import org.apache.wicket.ng.request.handler.PageAndComponentProvider;
+import org.apache.wicket.ng.request.handler.PageProvider;
+import org.apache.wicket.ng.request.handler.impl.ListenerInterfaceRequestHandler;
+import org.apache.wicket.ng.request.handler.impl.RenderPageRequestHandler;
+import org.apache.wicket.ng.request.listener.RequestListenerInterface;
+import org.apache.wicket.ng.request.mapper.info.ComponentInfo;
+import org.apache.wicket.ng.request.mapper.info.PageComponentInfo;
+import org.apache.wicket.ng.request.mapper.info.PageInfo;
+
+/**
+ * Decodes and encodes the following URLs:
+ *
+ * <pre>
+ * Page Instance - Render (RenderPageRequestHandler)
+ * /wicket/page?2
+ *
+ *
+ * Page Instance - Listener (ListenerInterfaceRequestHandler)
+ * /wicket/page?2-click-foo-bar-baz
+ * /wicket/page?2-click.1-foo-bar-baz (1 is behavior index)
+ * </pre>
+ *
+ * @author Matej Knopp
+ */
+public class PageInstanceMapper extends AbstractMapper
+{
+
+ /**
+ * Construct.
+ */
+ public PageInstanceMapper()
+ {
+ }
+
+ public RequestHandler mapRequest(Request request)
+ {
+ Url url = request.getUrl();
+ if (urlStartsWith(url, getContext().getNamespace(), getContext().getPageIdentifier()))
+ {
+ PageComponentInfo info = getPageComponentInfo(url);
+ if (info != null && info.getPageInfo().getPageId() != null)
+ {
+ Integer renderCount = info.getComponentInfo() != null ? info.getComponentInfo().getRenderCount() : null;
+
+ if (info.getComponentInfo() == null)
+ {
+ PageProvider provider = new PageProvider(info.getPageInfo().getPageId(), renderCount);
+ provider.setPageSource(getContext());
+ // render page
+ return new RenderPageRequestHandler(provider);
+ }
+ else
+ {
+ ComponentInfo componentInfo = info.getComponentInfo();
+
+ PageAndComponentProvider provider = new PageAndComponentProvider(info.getPageInfo()
+ .getPageId(), renderCount, componentInfo.getComponentPath());
+
+ provider.setPageSource(getContext());
+
+ // listener interface
+ RequestListenerInterface listenerInterface = requestListenerInterfaceFromString(componentInfo
+ .getListenerInterface());
+
+ return new ListenerInterfaceRequestHandler(provider, listenerInterface, componentInfo
+ .getBehaviorIndex());
+ }
+ }
+ }
+ return null;
+ }
+
+ public Url mapHandler(RequestHandler requestHandler)
+ {
+ PageComponentInfo info = null;
+
+ if (requestHandler instanceof RenderPageRequestHandler)
+ {
+ RequestablePage page = ((RenderPageRequestHandler) requestHandler).getPage();
+
+ PageInfo i = new PageInfo(page);
+ info = new PageComponentInfo(i, null);
+ }
+ else if (requestHandler instanceof ListenerInterfaceRequestHandler)
+ {
+ ListenerInterfaceRequestHandler handler = (ListenerInterfaceRequestHandler) requestHandler;
+ RequestablePage page = handler.getPage();
+ String componentPath = handler.getComponent().getPath();
+ RequestListenerInterface listenerInterface = handler.getListenerInterface();
+
+ PageInfo pageInfo = new PageInfo(page);
+ ComponentInfo componentInfo = new ComponentInfo(page.getRenderCount(),
+ requestListenerInterfaceToString(listenerInterface), componentPath, handler.getBehaviorIndex());
+ info = new PageComponentInfo(pageInfo, componentInfo);
+ }
+
+ if (info != null)
+ {
+ Url url = new Url();
+ url.getSegments().add(getContext().getNamespace());
+ url.getSegments().add(getContext().getPageIdentifier());
+ encodePageComponentInfo(url, info);
+ return url;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public int getCompatibilityScore(Request request)
+ {
+ // always return 0 here so that the mounts have higher priority
+ return 0;
+ }
+}
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/PageSource.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/PageSource.java?rev=823984&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/PageSource.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/PageSource.java Sun Oct 11 00:02:25 2009
@@ -0,0 +1,28 @@
+package org.apache.wicket.ng.request.mapper;
+
+import org.apache.wicket.ng.request.component.PageParameters;
+import org.apache.wicket.ng.request.component.RequestablePage;
+
+public interface PageSource
+{
+ /**
+ * Returns existing page instance if the page exists.
+ *
+ * @param pageId
+ * @return page instance or <code>null</code> if the page does not exist.
+ */
+ public RequestablePage getPageInstance(int pageId);
+
+ /**
+ * Creates new page instance of page with given class. The page should be marked as create
+ * bookmarkable, so subsequent calls to {@link RequestablePage#wasCreatedBookmarkable()} must return
+ * <code>true</code>
+ *
+ * @param pageMapName
+ * @param pageClass
+ * @param pageParameters
+ * @return new page instance
+ */
+ public RequestablePage newPageInstance(Class<? extends RequestablePage> pageClass, PageParameters pageParameters);
+
+}
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/ResourceReferenceMapper.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/ResourceReferenceMapper.java?rev=823984&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/ResourceReferenceMapper.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/ResourceReferenceMapper.java Sun Oct 11 00:02:25 2009
@@ -0,0 +1,156 @@
+/*
+ * 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 org.apache.wicket.ng.request.mapper;
+
+import org.apache.wicket.ng.request.Request;
+import org.apache.wicket.ng.request.RequestHandler;
+import org.apache.wicket.ng.request.Url;
+import org.apache.wicket.ng.request.component.PageParameters;
+import org.apache.wicket.ng.request.handler.resource.ResourceReferenceRequestHandler;
+import org.apache.wicket.ng.request.handler.resource.ResourceRequestHandler;
+import org.apache.wicket.ng.request.mapper.parameters.PageParametersEncoder;
+import org.apache.wicket.ng.request.mapper.parameters.SimplePageParametersEncoder;
+import org.apache.wicket.ng.resource.Resource;
+import org.apache.wicket.ng.resource.ResourceReference;
+import org.apache.wicket.ng.util.lang.Classes;
+
+/**
+ * Generic {@link ResourceReference} encoder that encodes and decodes non-mounted
+ * {@link ResourceReference}s.
+ * <p>
+ * Decodes and encodes the following URLs:
+ *
+ * <pre>
+ * /wicket/resource/org.apache.wicket.ResourceScope/name
+ * /wicket/resource/org.apache.wicket.ResourceScope/name?en
+ * /wicket/resource/org.apache.wicket.ResourceScope/name?-style
+ * /wicket/resource/org.apache.wicket.ResourceScope/resource/name.xyz?en_EN-style
+ * </pre>
+ *
+ * @author Matej Knopp
+ */
+public class ResourceReferenceMapper extends AbstractResourceReferenceMapper
+{
+ private final PageParametersEncoder pageParametersEncoder;
+
+ /**
+ * Construct.
+ *
+ * @param pageParametersEncoder
+ */
+ public ResourceReferenceMapper(PageParametersEncoder pageParametersEncoder)
+ {
+ this.pageParametersEncoder = pageParametersEncoder;
+ }
+
+ /**
+ * Construct.
+ */
+ public ResourceReferenceMapper()
+ {
+ this(new SimplePageParametersEncoder());
+ }
+
+ public RequestHandler mapRequest(Request request)
+ {
+ Url url = request.getUrl();
+ if (url.getSegments().size() >= 4
+ && urlStartsWith(url, getContext().getNamespace(), getContext().getResourceIdentifier()))
+ {
+ String className = url.getSegments().get(2);
+ StringBuilder name = new StringBuilder();
+ for (int i = 3; i < url.getSegments().size(); ++i)
+ {
+ if (name.length() > 0)
+ {
+ name.append("/");
+ }
+ name.append(url.getSegments().get(i));
+ }
+
+ ResourceReferenceAttributes attributes = getResourceReferenceAttributes(url);
+
+ // extract the PageParameters from URL if there are any
+ PageParameters pageParameters = extractPageParameters(request, url.getSegments().size(),
+ pageParametersEncoder);
+
+ Class<?> scope = resolveClass(className);
+ if (scope != null)
+ {
+ ResourceReference res = getContext().getResourceReferenceRegistry().getResourceReference(scope,
+ name.toString(), attributes.locale, attributes.style, false);
+ if (res != null)
+ {
+ Resource resource = res.getResource();
+ if (resource != null)
+ {
+ ResourceRequestHandler handler = new ResourceRequestHandler(resource, attributes.locale,
+ attributes.style, pageParameters);
+ return handler;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ protected Class<?> resolveClass(String name)
+ {
+ return Classes.resolveClass(name);
+ }
+
+ protected String getClassName(Class<?> scope)
+ {
+ return scope.getName();
+ }
+
+ public Url mapHandler(RequestHandler requestHandler)
+ {
+ if (requestHandler instanceof ResourceReferenceRequestHandler)
+ {
+ ResourceReferenceRequestHandler referenceRequestHandler = (ResourceReferenceRequestHandler) requestHandler;
+ ResourceReference reference = referenceRequestHandler.getResourceReference();
+ Url url = new Url();
+ url.getSegments().add(getContext().getNamespace());
+ url.getSegments().add(getContext().getResourceIdentifier());
+ url.getSegments().add(getClassName(reference.getScope()));
+ String nameParts[] = reference.getName().split("/");
+ for (String name : nameParts)
+ {
+ url.getSegments().add(name);
+ }
+ encodeResourceReferenceAttributes(url, reference);
+ PageParameters parameters = referenceRequestHandler.getPageParameters();
+ if (parameters != null)
+ {
+ parameters = new PageParameters(parameters);
+ // need to remove indexed parameters otherwise the URL won't be able to decode
+ parameters.clearIndexedParameters();
+ url = encodePageParameters(url, parameters, pageParametersEncoder);
+ }
+ return url;
+ }
+ return null;
+ }
+
+ public int getCompatibilityScore(Request request)
+ {
+ // always return 0 here so that the mounts have higher priority
+ return 0;
+ }
+
+}
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/StalePageException.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/StalePageException.java?rev=823984&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/StalePageException.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/StalePageException.java Sun Oct 11 00:02:25 2009
@@ -0,0 +1,52 @@
+/*
+ * 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 org.apache.wicket.ng.request.mapper;
+
+import org.apache.wicket.ng.WicketRuntimeException;
+import org.apache.wicket.ng.request.component.RequestablePage;
+
+/**
+ * Exception invoked when when stale link has been clicked. The page should then be rerendered
+ * with an explanatory error message.
+ *
+ * @author Matej Knopp
+ */
+public class StalePageException extends WicketRuntimeException
+{
+ private static final long serialVersionUID = 1L;
+
+ private final RequestablePage page;
+
+ /**
+ *
+ * Construct.
+ * @param page
+ */
+ public StalePageException(RequestablePage page)
+ {
+ this.page = page;
+ }
+
+ /**
+ *
+ * @return page instance
+ */
+ public RequestablePage getPage()
+ {
+ return page;
+ }
+}
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/SystemMapper.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/SystemMapper.java?rev=823984&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/SystemMapper.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/SystemMapper.java Sun Oct 11 00:02:25 2009
@@ -0,0 +1,48 @@
+package org.apache.wicket.ng.request.mapper;
+
+import org.apache.wicket.ng.request.Request;
+import org.apache.wicket.ng.request.RequestHandler;
+import org.apache.wicket.ng.request.RequestMapper;
+import org.apache.wicket.ng.request.Url;
+
+/**
+ * Mapper that encapsulates mappers that are necessary for Wicket to function.
+ *
+ * @author igor.vaynberg
+ *
+ */
+public class SystemMapper implements RequestMapper
+{
+ private ThreadsafeCompoundRequestMapper mapper = new ThreadsafeCompoundRequestMapper();
+
+ /**
+ * Constructor
+ */
+ public SystemMapper()
+ {
+ mapper.register(new PageInstanceMapper());
+ mapper.register(new BookmarkableMapper());
+ mapper.register(new ResourceReferenceMapper());
+ mapper.register(new BufferedResponseMapper());
+ }
+
+ /** {@inheritDoc} */
+ public int getCompatibilityScore(Request request)
+ {
+ return mapper.getCompatibilityScore(request);
+ }
+
+ /** {@inheritDoc} */
+ public Url mapHandler(RequestHandler handler)
+ {
+ return mapper.mapHandler(handler);
+ }
+
+ /** {@inheritDoc} */
+ public RequestHandler mapRequest(Request request)
+ {
+ return mapper.mapRequest(request);
+ }
+
+
+}
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/ThreadsafeCompoundRequestMapper.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/ThreadsafeCompoundRequestMapper.java?rev=823984&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/ThreadsafeCompoundRequestMapper.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/ThreadsafeCompoundRequestMapper.java Sun Oct 11 00:02:25 2009
@@ -0,0 +1,157 @@
+/*
+ * 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 org.apache.wicket.ng.request.mapper;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.apache.wicket.ng.request.CompoundRequestMapper;
+import org.apache.wicket.ng.request.Request;
+import org.apache.wicket.ng.request.RequestHandler;
+import org.apache.wicket.ng.request.RequestMapper;
+import org.apache.wicket.ng.request.Url;
+
+
+
+/**
+ * Thread safe compound {@link RequestMapper}. The mappers are searched depending on their
+ * compatibility score and the orders they were registered. If two or more {@link RequestMapper}s
+ * have the same compatibility score, the last registered mapper has highest priority.
+ *
+ * @author Matej Knopp
+ */
+public class ThreadsafeCompoundRequestMapper implements CompoundRequestMapper
+{
+ /* (non-Javadoc)
+ * @see org.apache.wicket.request.ICompoundRequestMapper#register(org.apache.wicket.request.IRequestMapper)
+ */
+ public void register(RequestMapper encoder)
+ {
+ mappers.add(0, encoder);
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.wicket.request.ICompoundRequestMapper#unregister(org.apache.wicket.request.IRequestMapper)
+ */
+ public void unregister(RequestMapper encoder)
+ {
+ mappers.remove(encoder);
+ }
+
+ private static class EncoderWithSegmentsCount implements Comparable<EncoderWithSegmentsCount>
+ {
+ private final RequestMapper mapper;
+ private final int compatibilityScore;
+
+ public EncoderWithSegmentsCount(RequestMapper encoder, int compatibilityScore)
+ {
+ this.mapper = encoder;
+ this.compatibilityScore = compatibilityScore;
+ }
+
+ public int compareTo(EncoderWithSegmentsCount o)
+ {
+ return o.compatibilityScore - this.compatibilityScore;
+ }
+
+ public RequestMapper getMapper()
+ {
+ return mapper;
+ }
+ };
+
+ /**
+ * Searches the registered {@link RequestMapper}s to find one that can decode the
+ * {@link Request}. Each registered {@link RequestMapper} is asked to provide the matching
+ * segments count. Then the encoders are asked to decode the request in order depending on the
+ * provided segments count.
+ * <p>
+ * The encoder with highest matching segments count that can decode the request is returned.
+ *
+ * @param request
+ * @return RequestHandler for the request or <code>null</code> if no encoder for the request is
+ * found.
+ */
+ public RequestHandler mapRequest(Request request)
+ {
+ List<EncoderWithSegmentsCount> list = new ArrayList<EncoderWithSegmentsCount>(mappers
+ .size());
+
+ for (RequestMapper encoder : mappers)
+ {
+ list.add(new EncoderWithSegmentsCount(encoder, encoder.getCompatibilityScore(request)));
+ }
+
+ Collections.sort(list);
+
+ for (EncoderWithSegmentsCount encoder : list)
+ {
+ RequestHandler handler = encoder.getMapper().mapRequest(request);
+ if (handler != null)
+ {
+ return handler;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Searches the registered {@link RequestMapper}s to find one that can encode the
+ * {@link RequestHandler}. Each registered {@link RequestMapper} is asked to encode the
+ * {@link RequestHandler} until an encoder that can encode the {@link RequestHandler} is found
+ * or no more encoders are left.
+ * <p>
+ * The handlers are searched in reverse order as they have been registered. More recently
+ * registered handlers have bigger priority.
+ *
+ * @param handler
+ * @return Url for the handler or <code>null</code> if no encoder for the handler is found.
+ */
+ public Url mapHandler(RequestHandler handler)
+ {
+ for (RequestMapper encoder : mappers)
+ {
+ Url url = encoder.mapHandler(handler);
+ if (url != null)
+ {
+ return url;
+ }
+ }
+ return null;
+ }
+
+ private List<RequestMapper> mappers = new CopyOnWriteArrayList<RequestMapper>();
+
+ /**
+ * The scope of the compound mapper is the highest score of the registered mappers.
+ *
+ * {@inheritDoc}
+ */
+ public int getCompatibilityScore(Request request)
+ {
+ int score = Integer.MIN_VALUE;
+ for (RequestMapper mapper : mappers)
+ {
+ score = Math.max(score, mapper.getCompatibilityScore(request));
+ }
+ return score;
+ }
+
+}
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/info/ComponentInfo.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/info/ComponentInfo.java?rev=823984&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/info/ComponentInfo.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/info/ComponentInfo.java Sun Oct 11 00:02:25 2009
@@ -0,0 +1,245 @@
+/*
+ * 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 org.apache.wicket.ng.request.mapper.info;
+
+import org.apache.wicket.ng.util.lang.Check;
+import org.apache.wicket.ng.util.string.Strings;
+
+/**
+ * Encodes listener inteface and component path in form of
+ * <listenerInterface>-<componentPath>,
+ * <listenerInterface>.<behaviorIndex>-<componentPath> or
+ * <render-count>.<listenerInterface>.<behaviorIndex>-<componentPath>
+ * <p>
+ * Component path is escaped (':' characters are replaced by '-')
+ *
+ * @author Matej Knopp
+ */
+public class ComponentInfo
+{
+ private final String listenerInterface;
+ private final String componentPath;
+ private final Integer behaviorIndex;
+ private final Integer renderCount;
+
+ private static final char BEHAVIOR_INDEX_SEPARATOR = '.';
+ private static final char SEPARATOR = '-';
+
+ /**
+ * Construct.
+ *
+ * @param renderCount
+ * @param listenerInterface
+ * @param componentPath
+ * @param behaviorIndex
+ */
+ public ComponentInfo(Integer renderCount, String listenerInterface, String componentPath,
+ Integer behaviorIndex)
+ {
+ Check.argumentNotEmpty(listenerInterface, "listenerInterface");
+ Check.argumentNotEmpty(componentPath, "componentPath");
+
+ this.listenerInterface = listenerInterface;
+ this.componentPath = componentPath;
+ this.behaviorIndex = behaviorIndex;
+ this.renderCount = renderCount;
+ }
+
+ /**
+ * @return component path
+ */
+ public String getComponentPath()
+ {
+ return componentPath;
+ }
+
+ /**
+ * @return listener interface name
+ */
+ public String getListenerInterface()
+ {
+ return listenerInterface;
+ }
+
+ /**
+ * @return behavior index
+ */
+ public Integer getBehaviorIndex()
+ {
+ return behaviorIndex;
+ }
+
+ /**
+ *
+ * @return render count
+ */
+ public Integer getRenderCount()
+ {
+ return renderCount;
+ }
+
+ private static final String TMP_PLACEHOLDER = "[[[[[[[WICKET[[TMP]]DASH]]" + Math.random() +
+ "]]]]";
+
+ private static String encodeComponentPath(String path)
+ {
+ if (path != null)
+ {
+ path = path.replace("" + SEPARATOR, TMP_PLACEHOLDER);
+ path = path.replace(':', SEPARATOR);
+ path = path.replace(TMP_PLACEHOLDER, "" + SEPARATOR + SEPARATOR);
+ return path;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ private static String decodeComponentPath(String path)
+ {
+ if (path != null)
+ {
+ path = path.replace("" + SEPARATOR + SEPARATOR, TMP_PLACEHOLDER);
+ path = path.replace(SEPARATOR, ':');
+ path = path.replace(TMP_PLACEHOLDER, "" + SEPARATOR);
+ return path;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuilder result = new StringBuilder();
+
+ if (renderCount != null)
+ {
+ result.append(renderCount);
+ result.append(BEHAVIOR_INDEX_SEPARATOR);
+ }
+
+ result.append(listenerInterface);
+
+ if (behaviorIndex != null)
+ {
+ result.append(BEHAVIOR_INDEX_SEPARATOR);
+ result.append(behaviorIndex);
+ }
+ result.append(SEPARATOR);
+ result.append(encodeComponentPath(componentPath));
+
+ return result.toString();
+ }
+
+ /**
+ * Method that rigidly checks if the string consists of digits only.
+ *
+ * @param string
+ * @return whether the string consists of digits only
+ */
+ private static boolean isNumber(String string)
+ {
+ if (string == null || string.length() == 0)
+ {
+ return false;
+ }
+ for (int i = 0; i < string.length(); ++i)
+ {
+ if (Character.isDigit(string.charAt(i)) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Parses the given string.
+ *
+ * @param string
+ * @return component info or <code>null</code> if the string is not in correct format.
+ */
+ public static ComponentInfo parse(String string)
+ {
+ if (Strings.isEmpty(string))
+ {
+ return null;
+ }
+ int i = string.indexOf(SEPARATOR);
+ if (i == -1)
+ {
+ return null;
+ }
+ else
+ {
+ String listenerInterface = string.substring(0, i);
+ String componentPath = decodeComponentPath(string.substring(i + 1));
+
+ if (Strings.isEmpty(listenerInterface))
+ {
+ return null;
+ }
+ if (Strings.isEmpty(componentPath))
+ {
+ return null;
+ }
+
+ Integer behaviorIndex = null;
+ Integer renderCount = null;
+
+ String listenerParts[] = Strings.split(listenerInterface, BEHAVIOR_INDEX_SEPARATOR);
+ if (listenerParts.length == 2)
+ {
+ if (isNumber(listenerParts[0]))
+ {
+ renderCount = Integer.valueOf(listenerParts[0]);
+ listenerInterface = listenerParts[1];
+ }
+ else if (isNumber(listenerParts[1]))
+ {
+ listenerInterface = listenerParts[0];
+ behaviorIndex = Integer.valueOf(listenerParts[1]);
+ }
+ else
+ {
+ return null;
+ }
+ }
+ else if (listenerParts.length == 3)
+ {
+ if (!isNumber(listenerParts[0]) && !isNumber(listenerParts[1]))
+ {
+ return null;
+ }
+ renderCount = Integer.valueOf(listenerParts[0]);
+ listenerInterface = listenerParts[1];
+ behaviorIndex = Integer.valueOf(listenerParts[2]);
+ }
+ else if (listenerParts.length != 1)
+ {
+ return null;
+ }
+
+ return new ComponentInfo(renderCount, listenerInterface, componentPath, behaviorIndex);
+ }
+ }
+
+}
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/info/PageComponentInfo.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/info/PageComponentInfo.java?rev=823984&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/info/PageComponentInfo.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/info/PageComponentInfo.java Sun Oct 11 00:02:25 2009
@@ -0,0 +1,117 @@
+/*
+ * 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 org.apache.wicket.ng.request.mapper.info;
+
+import org.apache.wicket.ng.util.lang.Check;
+import org.apache.wicket.ng.util.string.Strings;
+
+/**
+ * Encapsulates both page and component info.
+ * Rendered in form of <pageInfo>:<componentInfo>
+ *
+ * @author Matej Knopp
+ */
+public class PageComponentInfo
+{
+ private final PageInfo pageInfo;
+ private final ComponentInfo componentInfo;
+
+ private static final char SEPARATOR = '-';
+
+ /**
+ * Construct.
+ * @param pageInfo
+ * @param componentInfo
+ */
+ public PageComponentInfo(PageInfo pageInfo, ComponentInfo componentInfo)
+ {
+ Check.argumentNotNull(pageInfo, "pageInfo");
+
+ this.pageInfo = pageInfo;
+ this.componentInfo = componentInfo;
+ }
+
+ /**
+ * @return page info instance
+ */
+ public PageInfo getPageInfo()
+ {
+ return pageInfo;
+ }
+
+ /**
+ * @return component info instance or <code>null</code>
+ */
+ public ComponentInfo getComponentInfo()
+ {
+ return componentInfo;
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuilder result = new StringBuilder();
+ if (pageInfo != null)
+ {
+ result.append(pageInfo.toString());
+ }
+ if (componentInfo != null)
+ {
+ result.append(SEPARATOR);
+ result.append(componentInfo);
+ }
+
+ return result.toString();
+ }
+
+ /**
+ * Parses the given string
+ *
+ * @param s
+ * @return {@link PageComponentInfo} or <code>null</code> if the string is not in valid format.
+ */
+ public static PageComponentInfo parse(String s)
+ {
+ if (Strings.isEmpty(s))
+ {
+ return null;
+ }
+
+ final PageInfo pageInfo;
+ final ComponentInfo componentInfo;
+
+ int i = s.indexOf(SEPARATOR);
+ if (i == -1)
+
+ {
+ pageInfo = PageInfo.parse(s);
+ componentInfo = null;
+ }
+ else
+ {
+ pageInfo = PageInfo.parse(s.substring(0, i));
+ componentInfo = ComponentInfo.parse(s.substring(i + 1));
+ }
+
+ if (pageInfo == null)
+ {
+ return null;
+ }
+
+ return new PageComponentInfo(pageInfo, componentInfo);
+ }
+}
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/info/PageInfo.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/info/PageInfo.java?rev=823984&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/info/PageInfo.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/info/PageInfo.java Sun Oct 11 00:02:25 2009
@@ -0,0 +1,119 @@
+/*
+ * 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 org.apache.wicket.ng.request.mapper.info;
+
+import org.apache.wicket.ng.request.component.RequestablePage;
+import org.apache.wicket.ng.util.lang.Check;
+import org.apache.wicket.ng.util.string.Strings;
+
+/**
+ * Possible string representation of PageInfo:
+ * <ul>
+ * <li>pageId
+ * </ul>
+ *
+ * @author Matej Knopp
+ */
+public class PageInfo
+{
+ private final Integer pageId;
+
+ /**
+ * Construct.
+ *
+ * @param pageId
+ */
+ public PageInfo(Integer pageId)
+ {
+ this.pageId = pageId;
+ }
+
+ /**
+ * Construct.
+ */
+ public PageInfo()
+ {
+ this((Integer)null);
+ }
+
+ /**
+ * Construct.
+ *
+ * @param page
+ */
+ public PageInfo(RequestablePage page)
+ {
+ Check.argumentNotNull(page, "page");
+
+ this.pageId = page.getPageId();
+ }
+
+ /**
+ * @return page id
+ */
+ public Integer getPageId()
+ {
+ return pageId;
+ }
+
+ /**
+ * <ul>
+ * <li>pageId
+ * <li>pageId.version
+ * <li>pageMap (only in if pagemap starts with a letter)
+ * <li>.pageMap
+ * <li>pageMap.pageId (only in if pageMap name starts with a letter)
+ * <li>pageMap.pageId.version
+ * </ul>
+ */
+ @Override
+ public String toString()
+ {
+ if (getPageId() == null)
+ {
+ return "";
+ }
+ else
+ {
+ return getPageId().toString();
+ }
+ }
+
+
+ /**
+ * @param src
+ * @return page insfo instance or <code>null</code> if the string couldn't have been parsed
+ */
+ public static PageInfo parse(String src)
+ {
+ if (Strings.isEmpty(src))
+ {
+ return new PageInfo();
+ }
+ else
+ {
+ try
+ {
+ return new PageInfo(Integer.valueOf(src));
+ }
+ catch (NumberFormatException e)
+ {
+ return null;
+ }
+ }
+ }
+};
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/mount/Mount.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/mount/Mount.java?rev=823984&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/mount/Mount.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/mount/Mount.java Sun Oct 11 00:02:25 2009
@@ -0,0 +1,31 @@
+package org.apache.wicket.ng.request.mapper.mount;
+
+import org.apache.wicket.ng.request.Url;
+
+public class Mount
+{
+ private final Url url;
+ private MountParameters mountParameters = new MountParameters();
+
+ public Mount(Url url)
+ {
+ this.url = url;
+ }
+
+ public void setMountParameters(MountParameters mountParameters)
+ {
+ this.mountParameters = mountParameters;
+ }
+
+ public MountParameters getMountParameters()
+ {
+ return mountParameters;
+ }
+
+ public Url getUrl()
+ {
+ return url;
+ }
+
+
+}
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/mount/MountMapper.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/mount/MountMapper.java?rev=823984&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/mount/MountMapper.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/mount/MountMapper.java Sun Oct 11 00:02:25 2009
@@ -0,0 +1,125 @@
+package org.apache.wicket.ng.request.mapper.mount;
+
+import org.apache.wicket.ng.request.Request;
+import org.apache.wicket.ng.request.RequestHandler;
+import org.apache.wicket.ng.request.RequestMapper;
+import org.apache.wicket.ng.request.Url;
+import org.apache.wicket.ng.request.mapper.AbstractMapper;
+import org.apache.wicket.ng.util.lang.Check;
+import org.apache.wicket.ng.util.string.StringValue;
+
+/**
+ * {@link RequestMapper} that can mount requests onto urls. TODO docs and unit test
+ *
+ * @author igor.vaynberg
+ */
+public class MountMapper extends AbstractMapper
+{
+ private final String[] mountSegments;
+ private final MountedRequestMapper mapper;
+
+ public MountMapper(String mountPath, MountedRequestMapper mapper)
+ {
+ Check.argumentNotEmpty(mountPath, "mountPath");
+ Check.argumentNotNull(mapper, "mapper");
+
+ this.mountSegments = getMountSegments(mountPath);
+ this.mapper = mapper;
+ }
+
+ public MountMapper(String mountPath, RequestMapper mapper)
+ {
+ Check.argumentNotEmpty(mountPath, "mountPath");
+ Check.argumentNotNull(mapper, "mapper");
+
+ this.mountSegments = getMountSegments(mountPath);
+ this.mapper = new UnmountedMapperAdapter(mapper);
+ }
+
+ public MountMapper(String mountPath, RequestHandler handler)
+ {
+ Check.argumentNotEmpty(mountPath, "mountPath");
+ Check.argumentNotNull(handler, "handler");
+
+ this.mountSegments = getMountSegments(mountPath);
+ this.mapper = new UnmountedRequestHandlerAdapter(handler);
+ }
+
+ public int getCompatibilityScore(Request request)
+ {
+ if (urlStartsWith(request.getUrl(), mountSegments))
+ {
+ return mountSegments.length + mapper.getCompatibilityScore(dismountRequest(request));
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ private Request dismountRequest(Request request)
+ {
+ Url dismountedUrl = new Url(request.getUrl());
+ dismountedUrl.removeLeadingSegments(mountSegments.length);
+ return request.requestWithUrl(dismountedUrl);
+ }
+
+
+ public final RequestHandler mapRequest(Request request)
+ {
+ final Url url = request.getUrl();
+
+ if (url.getSegments().size() >= mountSegments.length && urlStartsWith(url, mountSegments))
+ {
+ MountParameters params = new MountParameters();
+ for (int i = 0; i < mountSegments.length; i++)
+ {
+ String placeholder = getPlaceholder(mountSegments[i]);
+ if (placeholder != null)
+ {
+ params.setValue(placeholder, StringValue.valueOf(url.getSegments().get(i)));
+ }
+ }
+
+ return mapper.mapRequest(dismountRequest(request), params);
+ }
+
+ return null;
+ }
+
+ public Url mapHandler(RequestHandler handler)
+ {
+ Mount mount = mapper.mapHandler(handler);
+
+ if (mount == null)
+ {
+ return null;
+ }
+
+ // TODO
+ // Check.notNull(mount.getUrl());
+ // Check.notNull(mount.getMountParameters());
+
+ for (int i = mountSegments.length; i > 0; i--)
+ {
+ String segment = mountSegments[i - 1];
+ String placeholder = getPlaceholder(segment);
+ String replacement = segment;
+
+ if (placeholder != null)
+ {
+ replacement = mount.getMountParameters().getValue(placeholder).toString();
+ if (replacement == null)
+ {
+ throw new IllegalStateException();// TODO message
+ }
+ }
+
+ mount.getUrl().getSegments().add(0, replacement);
+ }
+
+ return mount.getUrl();
+ }
+
+
+}
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/mount/MountParameters.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/mount/MountParameters.java?rev=823984&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/mount/MountParameters.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/mount/MountParameters.java Sun Oct 11 00:02:25 2009
@@ -0,0 +1,74 @@
+package org.apache.wicket.ng.request.mapper.mount;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.wicket.ng.util.string.StringValue;
+
+/**
+ * Mount parameters
+ *
+ * TODO docs and unit test
+ *
+ * @author igor.vaynberg
+ *
+ */
+public class MountParameters
+{
+ private final Map<String, String> map = new HashMap<String, String>();
+
+ public final StringValue getValue(String parameterName)
+ {
+ return StringValue.valueOf(map.get(parameterName));
+ }
+
+ public final void setValue(String parameterName, StringValue value)
+ {
+ map.put(parameterName, value.toString());
+ }
+
+ public final Collection<String> getParameterNames()
+ {
+ return map.keySet();
+ }
+
+ @Override
+ public int hashCode()
+ {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((map == null) ? 0 : map.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ MountParameters other = (MountParameters)obj;
+ if (map == null)
+ {
+ if (other.map != null)
+ return false;
+ }
+ else if (!map.equals(other.map))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "MountParameters [" + map + "]";
+ }
+
+
+
+
+}
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/mount/MountedRequestMapper.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/mount/MountedRequestMapper.java?rev=823984&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/mount/MountedRequestMapper.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/mount/MountedRequestMapper.java Sun Oct 11 00:02:25 2009
@@ -0,0 +1,53 @@
+package org.apache.wicket.ng.request.mapper.mount;
+
+import org.apache.wicket.ng.request.Request;
+import org.apache.wicket.ng.request.RequestHandler;
+
+/**
+ * TODO javadoc, explain "parameters resolved from the mount"
+ *
+ * @author igor.vaynberg
+ *
+ */
+public interface MountedRequestMapper
+{
+ /**
+ * Returns {@link RequestHandler} for the request or <code>null</code> if the encoder does not
+ * recognize the URL.
+ *
+ * @param request
+ * provides access to request data (i.e. Url and Parameters)
+ * @param mountParams
+ * parameters resolved from the mount
+ * @return RequestHandler instance or <code>null</code>
+ */
+ RequestHandler mapRequest(Request request, MountParameters mountParams);
+
+ /**
+ * Returns the score representing how compatible this request mapper is to processing the given
+ * request. When a request comes in all mappers are scored and are tried in order from highest
+ * score to lowest.
+ * <p>
+ * A good criteria for calculating the score is the number of matched url segments. For example
+ * when there are two encoders for mounted page, one mapped to <code>/foo</code> another to
+ * <code>/foo/bar</code> and the incomming reqest URL is </code>/foo/bar/baz</code>, the encoder
+ * mapped to <code>/foo/bar</code> will handle the request first as it has matching segments
+ * count of 2 while the first one has only matching segments count of 1.
+ * <p>
+ * Note that the method can return value greater then zero even if the encoder can not decode
+ * the request.
+ *
+ * @param request
+ * @return count of matching segments
+ */
+ int getCompatibilityScore(Request request);
+
+ /**
+ * Returns the {@link Mount} for given {@link RequestHandler} or <code>null</code> if the
+ * encoder does not recognize the request handler.
+ *
+ * @param requestHandler
+ * @return Url instance or <code>null</code>.
+ */
+ Mount mapHandler(RequestHandler requestHandler);
+}
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/mount/UnmountedMapperAdapter.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/mount/UnmountedMapperAdapter.java?rev=823984&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/mount/UnmountedMapperAdapter.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/mount/UnmountedMapperAdapter.java Sun Oct 11 00:02:25 2009
@@ -0,0 +1,45 @@
+package org.apache.wicket.ng.request.mapper.mount;
+
+import org.apache.wicket.ng.request.Request;
+import org.apache.wicket.ng.request.RequestHandler;
+import org.apache.wicket.ng.request.RequestMapper;
+import org.apache.wicket.ng.request.Url;
+
+/**
+ * Adapts a {@link RequestMapper} to be used as a {@link MountedRequestMapper}
+ *
+ * TODO javadoc
+ *
+ * @author igor.vaynberg
+ *
+ */
+class UnmountedMapperAdapter implements MountedRequestMapper
+{
+ private final RequestMapper mapper;
+
+ public UnmountedMapperAdapter(RequestMapper mapper)
+ {
+ super();
+ this.mapper = mapper;
+ }
+
+ public int getCompatibilityScore(Request request)
+ {
+ return mapper.getCompatibilityScore(request);
+ }
+
+ public Mount mapHandler(RequestHandler requestHandler)
+ {
+ Url url = mapper.mapHandler(requestHandler);
+ if (url != null)
+ {
+ return new Mount(url);
+ }
+ return null;
+ }
+
+ public RequestHandler mapRequest(Request request, MountParameters mountParams)
+ {
+ return mapper.mapRequest(request);
+ }
+}
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/mount/UnmountedRequestHandlerAdapter.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/mount/UnmountedRequestHandlerAdapter.java?rev=823984&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/mount/UnmountedRequestHandlerAdapter.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/mount/UnmountedRequestHandlerAdapter.java Sun Oct 11 00:02:25 2009
@@ -0,0 +1,43 @@
+package org.apache.wicket.ng.request.mapper.mount;
+
+import org.apache.wicket.ng.request.Request;
+import org.apache.wicket.ng.request.RequestHandler;
+import org.apache.wicket.ng.request.Url;
+
+/**
+ * Adapts a singleton {@link RequestHandler} instance to {@link MountedRequestMapper}
+ *
+ * TODO javadoc
+ *
+ * @author igor.vaynberg
+ *
+ */
+class UnmountedRequestHandlerAdapter implements MountedRequestMapper
+{
+ private final RequestHandler handler;
+
+ public UnmountedRequestHandlerAdapter(RequestHandler handler)
+ {
+ this.handler = handler;
+ }
+
+ public int getCompatibilityScore(Request request)
+ {
+ return 0;
+ }
+
+ public Mount mapHandler(RequestHandler requestHandler)
+ {
+ if (requestHandler.equals(handler))
+ {
+ return new Mount(new Url());
+ }
+ return null;
+ }
+
+ public RequestHandler mapRequest(Request request, MountParameters mountParams)
+ {
+ return handler;
+ }
+
+}
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/parameters/PageParametersEncoder.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/parameters/PageParametersEncoder.java?rev=823984&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/parameters/PageParametersEncoder.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/parameters/PageParametersEncoder.java Sun Oct 11 00:02:25 2009
@@ -0,0 +1,48 @@
+/*
+ * 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 org.apache.wicket.ng.request.mapper.parameters;
+
+import org.apache.wicket.ng.request.Request;
+import org.apache.wicket.ng.request.RequestHandler;
+import org.apache.wicket.ng.request.Url;
+import org.apache.wicket.ng.request.component.PageParameters;
+
+/**
+ * Encoder that can encode and decode {@link PageParameters} to/from URL.
+ *
+ * @author Matej Knopp
+ */
+public interface PageParametersEncoder
+{
+ /**
+ * Encode the given {@link PageParameters} instance into URL. The URL will be then merged with
+ * the URL generated for {@link RequestHandler}.
+ *
+ * @param pageParameters
+ * @return Url generated from the page parameters
+ */
+ public Url encodePageParameters(PageParameters pageParameters);
+
+ /**
+ * Decodes the given URL to {@link PageParameters}. The URL will have all
+ * {@link RequestHandler} specified segments/parameters stripped.
+ *
+ * @param request
+ * @return {@link PageParameters} instance
+ */
+ public PageParameters decodePageParameters(Request requuest);
+}
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/parameters/SimplePageParametersEncoder.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/parameters/SimplePageParametersEncoder.java?rev=823984&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/parameters/SimplePageParametersEncoder.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/mapper/parameters/SimplePageParametersEncoder.java Sun Oct 11 00:02:25 2009
@@ -0,0 +1,85 @@
+/*
+ * 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 org.apache.wicket.ng.request.mapper.parameters;
+
+import java.util.List;
+
+import org.apache.wicket.ng.request.Request;
+import org.apache.wicket.ng.request.Url;
+import org.apache.wicket.ng.request.Url.QueryParameter;
+import org.apache.wicket.ng.request.component.PageParameters;
+import org.apache.wicket.ng.util.string.StringValue;
+
+/**
+ * Simple encoder with direct indexed/named parameters mapping.
+ *
+ * @author Matej Knopp
+ */
+public class SimplePageParametersEncoder implements PageParametersEncoder
+{
+ /**
+ * Construct.
+ */
+ public SimplePageParametersEncoder()
+ {
+ }
+
+ public PageParameters decodePageParameters(Request request)
+ {
+ PageParameters parameters = new PageParameters();
+
+ int i = 0;
+ for (String s : request.getUrl().getSegments())
+ {
+ parameters.setIndexedParameter(i, s);
+ ++i;
+ }
+
+ for (QueryParameter p : request.getUrl().getQueryParameters())
+ {
+ parameters.addNamedParameter(p.getName(), p.getValue());
+ }
+
+ return parameters;
+ }
+
+ public Url encodePageParameters(PageParameters pageParameters)
+ {
+ Url url = new Url();
+
+ for (int i = 0; i < pageParameters.getIndexedParamsCount(); ++i)
+ {
+ url.getSegments().add(pageParameters.getIndexedParameter(i).toString());
+ }
+
+ for (String key : pageParameters.getNamedParameterKeys())
+ {
+ List<StringValue> values = pageParameters.getNamedParameters(key);
+ if (values != null)
+ {
+ for (StringValue value : values)
+ {
+ QueryParameter param = new QueryParameter(key, value.toString());
+ url.getQueryParameters().add(param);
+ }
+ }
+ }
+
+ return url;
+ }
+
+}
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/parameter/CombinedRequestParametersAdapter.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/parameter/CombinedRequestParametersAdapter.java?rev=823984&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/parameter/CombinedRequestParametersAdapter.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/parameter/CombinedRequestParametersAdapter.java Sun Oct 11 00:02:25 2009
@@ -0,0 +1,76 @@
+package org.apache.wicket.ng.request.parameter;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.wicket.ng.request.RequestParameters;
+import org.apache.wicket.ng.util.string.StringValue;
+
+public class CombinedRequestParametersAdapter implements RequestParameters
+{
+ private final RequestParameters parameters[];
+
+ public CombinedRequestParametersAdapter(RequestParameters ... parameters)
+ {
+ if (parameters == null)
+ {
+ throw new IllegalStateException("Argument 'parameters' may not be null");
+ }
+ this.parameters = parameters;
+ }
+
+ public Set<String> getParameterNames()
+ {
+ Set<String> result = new HashSet<String>();
+ for (RequestParameters p : parameters)
+ {
+ result.addAll(p.getParameterNames());
+ }
+ return Collections.unmodifiableSet(result);
+ }
+
+ public StringValue getParameterValue(String name)
+ {
+ for (RequestParameters p : parameters)
+ {
+ StringValue value = p.getParameterValue(name);
+ if (!value.isNull())
+ {
+ return value;
+ }
+ }
+ return StringValue.valueOf((String)null);
+ }
+
+ public List<StringValue> getParameterValues(String name)
+ {
+ List<StringValue> result = new ArrayList<StringValue>();
+ for (RequestParameters p : parameters)
+ {
+ List<StringValue> values = p.getParameterValues(name);
+ if (values != null)
+ {
+ for (StringValue v : values)
+ {
+ if (!result.contains(v))
+ {
+ result.add(v);
+ }
+ }
+ }
+ }
+
+ if (result.isEmpty())
+ {
+ return null;
+ }
+ else
+ {
+ return Collections.unmodifiableList(result);
+ }
+ }
+
+}
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/parameter/EmptyRequestParameters.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/parameter/EmptyRequestParameters.java?rev=823984&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/parameter/EmptyRequestParameters.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/parameter/EmptyRequestParameters.java Sun Oct 11 00:02:25 2009
@@ -0,0 +1,34 @@
+package org.apache.wicket.ng.request.parameter;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.wicket.ng.request.RequestParameters;
+import org.apache.wicket.ng.util.string.StringValue;
+
+public class EmptyRequestParameters implements RequestParameters
+{
+
+ private EmptyRequestParameters()
+ {
+ }
+
+ public static EmptyRequestParameters INSTANCE = new EmptyRequestParameters();
+
+ public Set<String> getParameterNames()
+ {
+ return Collections.emptySet();
+ }
+
+ public StringValue getParameterValue(String name)
+ {
+ return StringValue.valueOf((String)null);
+ }
+
+ public List<StringValue> getParameterValues(String name)
+ {
+ return null;
+ }
+
+}
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/parameter/UrlRequestParametersAdapter.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/parameter/UrlRequestParametersAdapter.java?rev=823984&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/parameter/UrlRequestParametersAdapter.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/parameter/UrlRequestParametersAdapter.java Sun Oct 11 00:02:25 2009
@@ -0,0 +1,83 @@
+/*
+ * 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 org.apache.wicket.ng.request.parameter;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.wicket.ng.request.RequestParameters;
+import org.apache.wicket.ng.request.Url;
+import org.apache.wicket.ng.request.Url.QueryParameter;
+import org.apache.wicket.ng.util.lang.Check;
+import org.apache.wicket.ng.util.lang.Objects;
+import org.apache.wicket.ng.util.string.StringValue;
+
+/**
+ * Utility class that expresses query parameters from {@link Url} as {@link RequestParameters}.
+ *
+ * @author Matej Knopp
+ */
+public class UrlRequestParametersAdapter implements RequestParameters
+{
+ private final Url url;
+
+ /**
+ * Construct.
+ * @param url
+ */
+ public UrlRequestParametersAdapter(Url url)
+ {
+ Check.argumentNotNull(url, "url");
+
+ this.url = url;
+ }
+
+ public Set<String> getParameterNames()
+ {
+ Set<String> result = new HashSet<String>();
+ for (QueryParameter parameter : url.getQueryParameters())
+ {
+ result.add(parameter.getName());
+ }
+ return Collections.unmodifiableSet(result);
+ }
+
+ public StringValue getParameterValue(String name)
+ {
+ return url.getQueryParameterValue(name);
+ }
+
+ public List<StringValue> getParameterValues(String name)
+ {
+ List<StringValue> values = null;
+ for (QueryParameter parameter : url.getQueryParameters())
+ {
+ if (Objects.equal(name, parameter.getName()))
+ {
+ if (values == null)
+ {
+ values = new ArrayList<StringValue>();
+ }
+ values.add(StringValue.valueOf(parameter.getValue()));
+ }
+ }
+ return values != null ? Collections.unmodifiableList(values) : null;
+ }
+}
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/response/BufferedWebResponse.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/response/BufferedWebResponse.java?rev=823984&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/response/BufferedWebResponse.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/response/BufferedWebResponse.java Sun Oct 11 00:02:25 2009
@@ -0,0 +1,249 @@
+/*
+ * 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 org.apache.wicket.ng.request.response;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.Cookie;
+
+import org.apache.wicket.ng.WicketRuntimeException;
+import org.apache.wicket.ng.util.lang.Check;
+
+/**
+ * Subclass of {@link WebResponse} that buffers the actions and performs those on another response.
+ *
+ * @see #writeTo(WebResponse)
+ *
+ * @author Matej Knopp
+ */
+public abstract class BufferedWebResponse extends WebResponse
+{
+
+ /**
+ * Construct.
+ */
+ public BufferedWebResponse()
+ {
+ }
+
+ private static class CookieEntry
+ {
+ Cookie cookie;
+ boolean add;
+ }
+
+ private List<CookieEntry> cookieEntries = new ArrayList<CookieEntry>();
+
+ @Override
+ public void addCookie(Cookie cookie)
+ {
+ CookieEntry entry = new CookieEntry();
+ entry.cookie = cookie;
+ entry.add = true;
+ cookieEntries.add(entry);
+ }
+
+ @Override
+ public void clearCookie(Cookie cookie)
+ {
+ CookieEntry entry = new CookieEntry();
+ entry.cookie = cookie;
+ entry.add = false;
+ cookieEntries.add(entry);
+ }
+
+ private Long contentLength = null;
+
+ @Override
+ public void setContentLength(long length)
+ {
+ contentLength = length;
+ }
+
+ private String contentType = null;
+
+ @Override
+ public void setContentType(String mimeType)
+ {
+ contentType = mimeType;
+ }
+
+ private Map<String, Long> dateHeaders = new HashMap<String, Long>();
+
+ @Override
+ public void setDateHeader(String name, long date)
+ {
+ dateHeaders.put(name, date);
+ }
+
+ private Map<String, String> headers = new HashMap<String, String>();
+
+ @Override
+ public void setHeader(String name, String value)
+ {
+ headers.put(name, value);
+ }
+
+ private StringBuilder builder;
+ private ByteArrayOutputStream stream;
+
+ @Override
+ public void write(CharSequence sequence)
+ {
+ if (stream != null)
+ {
+ throw new IllegalStateException(
+ "Can't call write(CharSequence) after write(byte[]) has been called.");
+ }
+
+ if (builder == null)
+ {
+ builder = new StringBuilder(4096);
+ }
+
+ builder.append(sequence);
+ }
+
+ @Override
+ public void write(byte[] array)
+ {
+ if (builder != null)
+ {
+ throw new IllegalStateException(
+ "Can't call write(byte[]) after write(CharSequence) has been called.");
+ }
+ if (stream == null)
+ {
+ stream = new ByteArrayOutputStream(array.length);
+ }
+ try
+ {
+ stream.write(array);
+ }
+ catch (IOException e)
+ {
+ throw new WicketRuntimeException(e);
+ }
+ }
+
+ private String redirectUrl = null;
+
+ @Override
+ public void sendRedirect(String url)
+ {
+ this.redirectUrl = url;
+ }
+
+ private Integer statusCode = null;
+
+ @Override
+ public void setStatus(int sc)
+ {
+ this.statusCode = sc;
+ }
+
+ /**
+ * Writes the content of the buffer to the specified response. Also sets the properties and and
+ * headers.
+ *
+ * @param response
+ */
+ public void writeTo(final WebResponse response)
+ {
+ Check.argumentNotNull(response, "response");
+
+ for (CookieEntry e : cookieEntries)
+ {
+ if (e.add)
+ {
+ response.addCookie(e.cookie);
+ }
+ else
+ {
+ response.clearCookie(e.cookie);
+ }
+ }
+ if (contentLength != null)
+ {
+ response.setContentLength(contentLength);
+ }
+ if (contentType != null)
+ {
+ response.setContentType(contentType);
+ }
+ for (String s : dateHeaders.keySet())
+ {
+ response.setDateHeader(s, dateHeaders.get(s));
+ }
+ for (String s : headers.keySet())
+ {
+ response.setHeader(s, headers.get(s));
+ }
+ if (statusCode != null)
+ {
+ response.setStatus(statusCode);
+ }
+ if (redirectUrl != null)
+ {
+ response.sendRedirect(redirectUrl);
+ }
+ if (builder != null)
+ {
+ response.write(builder);
+ }
+ else if (stream != null)
+ {
+ final boolean copied[] = { false };
+ try
+ {
+ // try to avoid copying the array
+ stream.writeTo(new OutputStream()
+ {
+ @Override
+ public void write(int b) throws IOException
+ {
+
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException
+ {
+ if (off == 0 && len == b.length)
+ {
+ response.write(b);
+ copied[0] = true;
+ }
+ }
+ });
+ }
+ catch (IOException e1)
+ {
+ throw new WicketRuntimeException(e1);
+ }
+ if (copied[0] == false)
+ {
+ response.write(stream.toByteArray());
+ }
+ }
+ }
+}
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/response/Response.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/response/Response.java?rev=823984&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/response/Response.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/response/Response.java Sun Oct 11 00:02:25 2009
@@ -0,0 +1,63 @@
+/*
+ * 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 org.apache.wicket.ng.request.response;
+
+/**
+ * Abstract base class for different implementations of response writing.
+ * <p>
+ * The implementation may not support calling both {@link #write(byte[])} and
+ * {@link #write(CharSequence)} on the same {@link Response} instance.
+ *
+ * @author Matej Knopp
+ */
+public abstract class Response
+{
+ /**
+ * Writes the {@link CharSequence} to output.
+ *
+ * @param sequence
+ * @throws IllegalStateException
+ * if {@link #write(byte[])} has already been called on this instance
+ */
+ public abstract void write(CharSequence sequence);
+
+ /**
+ * Writes the buffer to output.
+ *
+ * @param array
+ * @throws IllegalStateException
+ * if {@link #write(CharSequence)} has already been called on this instance
+ */
+ public abstract void write(byte[] array);
+
+ /**
+ * Closes the response
+ */
+ public void close()
+ {
+ }
+
+
+ /**
+ * Encodes the specified URL by including the session ID in it,
+ * or, if encoding is not needed, returns the URL unchanged.
+ *
+ * @param url
+ * @return encoded URL
+ */
+ public abstract String encodeURL(String url);
+}
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/response/ServletWebResponse.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/response/ServletWebResponse.java?rev=823984&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/response/ServletWebResponse.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/response/ServletWebResponse.java Sun Oct 11 00:02:25 2009
@@ -0,0 +1,170 @@
+/*
+ * 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 org.apache.wicket.ng.request.response;
+
+import java.io.IOException;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.wicket.ng.WicketRuntimeException;
+import org.apache.wicket.ng.util.lang.Check;
+
+/**
+ * WebResponse that wraps a {@link ServletWebResponse}.
+ * @author Matej Knopp
+ */
+public class ServletWebResponse extends WebResponse
+{
+ private final HttpServletResponse httpServletResponse;
+
+ /**
+ * Construct.
+
+ * @param httpServletResponse
+ */
+ public ServletWebResponse(HttpServletResponse httpServletResponse)
+ {
+ Check.argumentNotNull(httpServletResponse, "httpServletResponse");
+
+ this.httpServletResponse = httpServletResponse;
+ }
+
+ /**
+ * Returns the wrapped response
+ *
+ * @return wrapped response
+ */
+ public final HttpServletResponse getHttpServletResponse()
+ {
+ return httpServletResponse;
+ }
+
+ @Override
+ public void addCookie(Cookie cookie)
+ {
+ httpServletResponse.addCookie(cookie);
+ }
+
+ @Override
+ public void clearCookie(Cookie cookie)
+ {
+ cookie.setMaxAge(0);
+ cookie.setValue(null);
+ addCookie(cookie);
+ }
+
+ @Override
+ public void setContentLength(long length)
+ {
+ httpServletResponse.setContentLength((int)length);
+ }
+
+ @Override
+ public void setContentType(String mimeType)
+ {
+ httpServletResponse.setContentType(mimeType);
+ }
+
+ @Override
+ public void setDateHeader(String name, long date)
+ {
+ httpServletResponse.setDateHeader(name, date);
+ }
+
+ @Override
+ public void setHeader(String name, String value)
+ {
+ httpServletResponse.setHeader(name, value);
+ }
+
+ @Override
+ public void write(CharSequence sequence)
+ {
+ try
+ {
+ httpServletResponse.getWriter().append(sequence);
+ }
+ catch (IOException e)
+ {
+ throw new WicketRuntimeException(e);
+ }
+ }
+
+ @Override
+ public void write(byte[] array)
+ {
+ try
+ {
+ httpServletResponse.getOutputStream().write(array);
+ }
+ catch (IOException e)
+ {
+ throw new WicketRuntimeException(e);
+ }
+ }
+
+ @Override
+ public void setStatus(int sc)
+ {
+ httpServletResponse.setStatus(sc);
+ }
+
+ @Override
+ public String encodeURL(String url)
+ {
+ if (url != null)
+ {
+ if (url.length() > 0 && url.charAt(0) == '?')
+ {
+ // there is a bug in apache tomcat 5.5 where tomcat doesn't put sessionid to url
+ // when the URL starts with '?'. So we prepend the URL with ./ and remove it
+ // afterwards (unless some container prepends session id before './' or mangles
+ // the URL otherwise
+
+ String encoded = httpServletResponse.encodeURL("./" + url.toString());
+ if (encoded.startsWith("./"))
+ {
+ return encoded.substring(2);
+ }
+ else
+ {
+ return encoded;
+ }
+ }
+ else
+ {
+ return httpServletResponse.encodeURL(url.toString());
+ }
+ }
+ return httpServletResponse.encodeURL(url);
+ }
+
+ @Override
+ public void sendRedirect(String url)
+ {
+ url = httpServletResponse.encodeRedirectURL(url);
+ try
+ {
+ httpServletResponse.sendRedirect(url);
+ }
+ catch (IOException e)
+ {
+ throw new WicketRuntimeException(e);
+ }
+ }
+}
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/response/StringResponse.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/response/StringResponse.java?rev=823984&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/response/StringResponse.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/response/StringResponse.java Sun Oct 11 00:02:25 2009
@@ -0,0 +1,35 @@
+package org.apache.wicket.ng.request.response;
+
+public class StringResponse extends Response
+{
+
+ private final StringBuilder builder = new StringBuilder();
+
+ public StringResponse()
+ {
+ }
+
+ @Override
+ public String encodeURL(String url)
+ {
+ return url;
+ }
+
+ @Override
+ public void write(CharSequence sequence)
+ {
+ builder.append(sequence);
+ }
+
+ @Override
+ public void write(byte[] array)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String toString()
+ {
+ return builder.toString();
+ }
+}
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/response/WebResponse.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/response/WebResponse.java?rev=823984&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/response/WebResponse.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/response/WebResponse.java Sun Oct 11 00:02:25 2009
@@ -0,0 +1,135 @@
+/*
+ * 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 org.apache.wicket.ng.request.response;
+
+import javax.servlet.http.Cookie;
+
+import org.apache.wicket.ng.util.string.Strings;
+
+
+/**
+ * Base class for web-related responses.
+ *
+ * @author Matej Knopp
+ */
+public abstract class WebResponse extends Response
+{
+ /**
+ * Add a cookie to the web response
+ *
+ * @param cookie
+ */
+ public abstract void addCookie(final Cookie cookie);
+
+ /**
+ * Convenience method for clearing a cookie.
+ *
+ * @param cookie
+ * The cookie to set
+ * @see WebResponse#addCookie(Cookie)
+ */
+ public abstract void clearCookie(final Cookie cookie);
+
+ /**
+ * Set a header to the string value in the servlet response stream.
+ *
+ * @param name
+ * @param value
+ */
+ public abstract void setHeader(String name, String value);
+
+ /**
+ * Set a header to the date value in the servlet response stream.
+ *
+ * @param name
+ * @param date
+ */
+ public abstract void setDateHeader(String name, long date);
+
+ /**
+ * Set the content length on the response, if appropriate in the subclass. This default
+ * implementation does nothing.
+ *
+ * @param length
+ * The length of the content
+ */
+ public abstract void setContentLength(final long length);
+
+ /**
+ * Set the content type on the response, if appropriate in the subclass. This default
+ * implementation does nothing.
+ *
+ * @param mimeType
+ * The mime type
+ */
+ public abstract void setContentType(final String mimeType);
+
+ /**
+ * Set the contents last modified time, if appropriate in the subclass.
+ *
+ * @param time
+ * The last modified time in milliseconds
+ */
+ public void setLastModifiedTime(long time)
+ {
+ setDateHeader("Last-Modified", time);
+ }
+
+ /**
+ * Convenience method for setting the content-disposition:attachment header. This header is used
+ * if the response should prompt the user to download it as a file instead of opening in a
+ * browser.
+ *
+ * @param filename
+ * file name of the attachment
+ */
+ public void setAttachmentHeader(String filename)
+ {
+ setHeader("Content-Disposition", "attachment" +
+ ((!Strings.isEmpty(filename)) ? ("; filename=\"" + filename + "\"") : ""));
+ }
+
+ /**
+ * Convenience method for setting the content-disposition:in;ine header. This header is used if
+ * the response should be shown embedded in browser window while having custom file name when
+ * user saves the response. browser.
+ *
+ * @param filename
+ * file name of the attachment
+ */
+ public void setInlineHeader(String filename)
+ {
+ setHeader("Content-Disposition", "inline" +
+ ((!Strings.isEmpty(filename)) ? ("; filename=\"" + filename + "\"") : ""));
+ }
+
+ /**
+ * Sets the status code for this response.
+ *
+ * @param sc status code
+ */
+ public abstract void setStatus(int sc);
+
+
+ /**
+ * Redirects the response to specified URL. The implementation is responsible for properly
+ * encoding the URL.
+ *
+ * @param url
+ */
+ public abstract void sendRedirect(String url);
+}
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/url-format.txt
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/url-format.txt?rev=823984&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/url-format.txt (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/request/url-format.txt Sun Oct 11 00:02:25 2009
@@ -0,0 +1,62 @@
+NOTE - According to http://www.rfc-editor.org/rfc/rfc1738.txt ':' is not a valid
+ character in URL and must be encoded.
+ In order for Wicket to produce valid URLs I've decided to use - as separator instead
+ This will only affect listener URLs anyway, which are not shown in location bar
+ (except for bookmarkable listeners on stateless pages)
+ '-' in component name is encoded as '--'.
+
+
+NOT BOOKMARKABLE
+----------------
+
+Page Instance - Render (RenderPageRequestHandler)
+/wicket/page?2
+
+Page Instance - Listener (ListenerInterfaceRequestHandler)
+/wicket/page?2-5.click-foo-bar-baz (5 is render count)
+
+Page Instance - Listener with behavior (ListenerInterfaceRequestHandler)
+/wicket/page?2-5.click.1-foo-bar-baz (5 is render count, 1 is behavior index)
+
+BOOKMARKABLE - NOT MOUNTED
+--------------------------
+
+Page Class - Render (BookmarkablePageRequestHandler)
+/wicket/bookmarkable/org.apache.wicket.MyPage
+/wicket/bookmarkable/org.apache.wicket.MyPage?pageMap
+(these will redirect to hybrid alternative if page is not stateless)
+
+Page Instance - Render Hybrid (RenderPageRequestHandler for pages that were created using bookmarkable URLs)
+/wicket/bookmarkable/org.apache.wicket.MyPage?2
+
+Page Instance - Bookmarkable Listener (BookmarkableListenerInterfaceRequestHandler)
+/wicket/bookmarkable/org.apache.wicket.MyPage?2-5.click-foo-bar-baz (5 is renderCount)
+/wicket/bookmarkable/org.apache.wicket.MyPage?2-5.click.1-foo-bar-baz (5 is renderCount, 1 is behavior index)
+(these will redirect to hybrid if page is not stateless)
+
+BOOKMARKABLE - MOUNTED
+----------------------
+
+Page Class - Render (BookmarkablePageRequestHandler for mounted pages)
+/mount/point
+/mount/point?pageMap
+(these will redirect to hybrid alternative if page is not stateless)
+
+Page Instance - Render Hybrid (RenderPageRequestHandler for mounted pages)
+/mount/point?2
+
+Page Instance - Bookmarkable Listener (BookmarkableListenerInterfaceRequestHandler for mounted pages)
+/mount/point?2-5.click-foo-bar-baz (5 is render count)
+/mount/point?2-5.click.1-foo-bar-baz (5 is render count, 1 is behavior index)
+(these will redirect to hybrid if page is not stateless)
+
+mount path can also contain parameter placeholders
+e.g. when mount path is /foo/${bar}/baz and the incoming url is /foo/abc/baz the extracted page parameters will
+contain named parameter bar="abc".
+
+RESOURCES
+---------
+/wicket/resource/org.apache.wicket.ResourceScope/resource/path.xyz?en_EN-style
+/mounted/resource?en_EN-style (with locale and style)
+/mounted/resource
+
Added: wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/resource/Resource.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/resource/Resource.java?rev=823984&view=auto
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/resource/Resource.java (added)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/ng/resource/Resource.java Sun Oct 11 00:02:25 2009
@@ -0,0 +1,134 @@
+/*
+ * 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 org.apache.wicket.ng.resource;
+
+import java.io.Serializable;
+import java.util.Locale;
+
+import org.apache.wicket.ng.request.Request;
+import org.apache.wicket.ng.request.component.PageParameters;
+import org.apache.wicket.ng.request.handler.resource.ResourceRequestHandler;
+import org.apache.wicket.ng.request.response.Response;
+import org.apache.wicket.ng.util.lang.Check;
+
+/**
+ * Resource is an object capable of writing output to response.
+ *
+ * @author Matej Knopp
+ */
+public interface Resource extends Serializable
+{
+ /**
+ * Attributes that are provided to resource in the {@link Resource#respond(Attributes)} method.
+ * Attributes are set by the {@link ResourceRequestHandler}.
+ *
+ * @author Matej Knopp
+ */
+ public static class Attributes
+ {
+ private final Request request;
+ private final Response response;
+ private final Locale locale;
+ private final String style;
+ private final PageParameters parameters;
+
+ /**
+ * Construct.
+ *
+ * @param request
+ *
+ * @param response
+ * @param locale
+ * @param style
+ * @param parameters
+ */
+ public Attributes(Request request, Response response, Locale locale, String style,
+ PageParameters parameters)
+ {
+ Check.argumentNotNull(request, "request");
+ Check.argumentNotNull(response, "response");
+ Check.argumentNotNull(locale, "locale");
+
+ this.request = request;
+ this.response = response;
+ this.locale = locale;
+ this.style = style;
+ this.parameters = parameters;
+ }
+
+ /**
+ * Returns current request.
+ *
+ * @return current request
+ */
+ public Request getRequest()
+ {
+ return request;
+ }
+
+ /**
+ * Returns current response. The resource must write output to the response.
+ *
+ * @return response
+ */
+ public Response getResponse()
+ {
+ return response;
+ }
+
+ /**
+ * Returns requested locale. The locale is never null.
+ *
+ * @return locale
+ */
+ public Locale getLocale()
+ {
+ return locale;
+ }
+
+ /**
+ * If specified returns requested style. The style is optional.
+ *
+ * @return style or <code>null</code>
+ */
+ public String getStyle()
+ {
+ return style;
+ }
+
+ /**
+ * Returns additional parameters extracted from the request. If resource is created mounted
+ * {@link ResourceReference}, this method returns all (indexed and query) parameters after
+ * the mount path. For non mounted {@link ResourceReference}s this method will only return
+ * the query parameters. For component specific resources the behavior depends on the
+ * component.
+ *
+ * @return page parameters or <code>null</code>
+ */
+ public PageParameters getParameters()
+ {
+ return parameters;
+ }
+ };
+
+ /**
+ * Renders this resource to response using the provided attributes.
+ *
+ * @param attributes
+ */
+ public void respond(Attributes attributes);
+}