001// Copyright 2008, 2010 The Apache Software Foundation 002// 003// Licensed under the Apache License, Version 2.0 (the "License"); 004// you may not use this file except in compliance with the License. 005// You may obtain a copy of the License at 006// 007// http://www.apache.org/licenses/LICENSE-2.0 008// 009// Unless required by applicable law or agreed to in writing, software 010// distributed under the License is distributed on an "AS IS" BASIS, 011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012// See the License for the specific language governing permissions and 013// limitations under the License. 014 015package org.apache.tapestry5.internal.services; 016 017import org.apache.tapestry5.EventContext; 018import org.apache.tapestry5.commons.services.TypeCoercer; 019import org.apache.tapestry5.internal.EmptyEventContext; 020import org.apache.tapestry5.internal.TapestryInternalUtils; 021import org.apache.tapestry5.internal.URLEventContext; 022import org.apache.tapestry5.ioc.internal.util.InternalUtils; 023import org.apache.tapestry5.services.ContextPathEncoder; 024import org.apache.tapestry5.services.ContextValueEncoder; 025import org.apache.tapestry5.services.URLEncoder; 026 027public class ContextPathEncoderImpl implements ContextPathEncoder 028{ 029 private static final int BUFFER_SIZE = 100; 030 031 private final ContextValueEncoder valueEncoder; 032 033 private final URLEncoder urlEncoder; 034 035 private final TypeCoercer typeCoercer; 036 037 private final EventContext EMPTY = new EmptyEventContext(); 038 039 public ContextPathEncoderImpl(ContextValueEncoder valueEncoder, URLEncoder urlEncoder, TypeCoercer typeCoercer) 040 { 041 this.valueEncoder = valueEncoder; 042 this.urlEncoder = urlEncoder; 043 this.typeCoercer = typeCoercer; 044 } 045 046 public String encodeValue(Object value) 047 { 048 String valueEncoded = value == null ? null : valueEncoder.toClient(value); 049 050 return urlEncoder.encode(valueEncoded); 051 } 052 053 public String encodeIntoPath(Object[] context) 054 { 055 if (context == null || context.length == 0) 056 return ""; 057 058 return encodeIntoPath(new ArrayEventContext(typeCoercer, context)); 059 } 060 061 public String encodeIntoPath(EventContext context) 062 { 063 assert context != null; 064 int count = context.getCount(); 065 066 StringBuilder output = new StringBuilder(BUFFER_SIZE); 067 068 for (int i = 0; i < count; i++) 069 { 070 Object raw = context.get(Object.class, i); 071 072 String urlEncoded = encodeValue(raw); 073 074 if (i > 0) 075 output.append('/'); 076 077 output.append(urlEncoded); 078 } 079 080 return output.toString(); 081 } 082 083 public EventContext decodePath(String path) 084 { 085 if (InternalUtils.isBlank(path)) 086 return EMPTY; 087 088 String[] split = TapestryInternalUtils.splitPath(path); 089 090 for (int i = 0; i < split.length; i++) 091 { 092 split[i] = urlEncoder.decode(split[i]); 093 } 094 095 return new URLEventContext(valueEncoder, split); 096 } 097}