diff options
Diffstat (limited to 'sca-java-2.x/branches/2.0-Beta3/modules/common-http')
9 files changed, 0 insertions, 712 deletions
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/common-http/META-INF/MANIFEST.MF b/sca-java-2.x/branches/2.0-Beta3/modules/common-http/META-INF/MANIFEST.MF deleted file mode 100644 index 4afe089d61..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/common-http/META-INF/MANIFEST.MF +++ /dev/null @@ -1,15 +0,0 @@ -Manifest-Version: 1.0 -SCA-Version: 1.1 -Bundle-Name: Apache Tuscany SCA Common HTTP -Bundle-Vendor: The Apache Software Foundation -Bundle-Version: 2.0.0 -Bundle-ManifestVersion: 2 -Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt -Bundle-Description: Apache Tuscany SCA Common HTTP -Bundle-SymbolicName: org.apache.tuscany.sca.common.http -Bundle-DocURL: http://www.apache.org/ -Export-Package: org.apache.tuscany.sca.common.http;version="2.0.0";uses:="javax.servlet.http" -Import-Package: javax.servlet.http -Bundle-RequiredExecutionEnvironment: J2SE-1.5,JavaSE-1.6 - - diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/common-http/pom.xml b/sca-java-2.x/branches/2.0-Beta3/modules/common-http/pom.xml deleted file mode 100644 index 8f510ff3a2..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/common-http/pom.xml +++ /dev/null @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - * 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. ---> -<project> - <modelVersion>4.0.0</modelVersion> - <parent> - <groupId>org.apache.tuscany.sca</groupId> - <artifactId>tuscany-modules</artifactId> - <version>2.0-Beta3-SNAPSHOT</version> - <relativePath>../pom.xml</relativePath> - </parent> - <artifactId>tuscany-common-http</artifactId> - <name>Apache Tuscany SCA Common HTTP</name> - - <dependencies> - <dependency> - <groupId>javax.servlet</groupId> - <artifactId>servlet-api</artifactId> - <version>2.5</version> - <scope>provided</scope> - </dependency> - - <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - <version>4.8.1</version> - <scope>test</scope> - </dependency> - </dependencies> - -</project> diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPCacheContext.java b/sca-java-2.x/branches/2.0-Beta3/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPCacheContext.java deleted file mode 100644 index 08faf6a14b..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPCacheContext.java +++ /dev/null @@ -1,280 +0,0 @@ -/* - * 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.tuscany.sca.common.http; - -import java.text.SimpleDateFormat; -import java.util.Date; - -import javax.servlet.http.HttpServletRequest; - -/** - * A class to store cache settings for Atom and HTTP requests and responses. - * - * Predicates are statements that work in conjunction with - * ETags and LastModified dates to determine if a precondition - * or postcondition is satisfied. - * See HTTP specification for how predicates wrk: - * http://tools.ietf.org/html/rfc2616 - * Example predicates in HTTP include If-Match, If-None-Match, - * If-Modified-Since, If-Unmodified-Since, If-Range. - * - * @version $Rev$ $Date$ - */ -public class HTTPCacheContext { - public static final SimpleDateFormat RFC822DateFormat = new SimpleDateFormat( "EEE, dd MMM yyyy HH:mm:ss Z" ); // RFC 822 date time - - public boolean enabled; - public String eTag; - public String lastModified; - public Date lastModifiedDate; - public boolean ifModifiedSince; - public boolean ifUnmodifiedSince; - public boolean ifMatch; - public boolean ifNoneMatch; - public boolean ifRange; - - - /** - * Enabled is true whenever ETag, LastModified, or predicate is set. - * @return the enabled - */ - public boolean isEnabled() { - return enabled; - } - - /** - * @param enabled the enabled to set - */ - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - /** - * An ETag is a unique ID for an item. It changes when - * a field in the item or the update date changes. - * See HTTP specification for how ETags work: - * http://tools.ietf.org/html/rfc2616 - * @return the eTag - */ - public String getETag() { - return eTag; - } - - /** - * @param tag the eTag to set - */ - public void setETag(String tag) { - eTag = tag; - enabled = true; - } - - /** - * The LastModified date is the time the item was last - * changed. See HTTP specification for how ETags work: - * http://tools.ietf.org/html/rfc2616 - * @return the lastModified - */ - public String getLastModified() { - return lastModified; - } - - /** - * The LastModified date is the time the item was last - * changed. See HTTP specification for how ETags work: - * http://tools.ietf.org/html/rfc2616 - * @return the lastModified - */ - public Date getLastModifiedAsDate() { - return lastModifiedDate; - } - - /** - * @param lastModified the lastModified to set - */ - public void setLastModified(String lastModified) throws java.text.ParseException { - this.lastModified = lastModified; - // Catch date formatting on input to help debugging. - lastModifiedDate = RFC822DateFormat.parse( lastModified ); - enabled = true; - } - - /** - * @param lastModified the lastModified to set - */ - public void setLastModified(Date updated) { - this.lastModified = RFC822DateFormat.format( updated ); - lastModifiedDate = updated; - enabled = true; - } - - /** - * @return the ifModifedSince - */ - public boolean isIfModifiedSince() { - return ifModifiedSince; - } - - /** - * @param ifModifedSince the ifModifedSince to set - */ - public void setIfModifiedSince(boolean ifModifiedSince) { - this.ifModifiedSince = ifModifiedSince; - if ( ifModifiedSince ) { - enabled = true; - } - } - - /** - * @return the ifUnModifiedSince - */ - public boolean isIfUnmodifiedSince() { - return ifUnmodifiedSince; - } - - /** - * @param ifUnModifiedSince the ifUnModifiedSince to set - */ - public void setIfUnmodifiedSince(boolean ifUnmodifiedSince) { - this.ifUnmodifiedSince = ifUnmodifiedSince; - if ( ifUnmodifiedSince ) { - enabled = true; - } - } - - /** - * @return the ifMatch - */ - public boolean isIfMatch() { - return ifMatch; - } - - /** - * @param ifMatch the ifMatch to set - */ - public void setIfMatch(boolean ifMatch) { - this.ifMatch = ifMatch; - if ( ifMatch ) { - enabled = true; - } - } - - /** - * @return the ifNoneMatch - */ - public boolean isIfNoneMatch() { - return ifNoneMatch; - } - - /** - * @param ifNoneMatch the ifNoneMatch to set - */ - public void setIfNoneMatch(boolean ifNoneMatch) { - this.ifNoneMatch = ifNoneMatch; - if ( ifNoneMatch ) { - enabled = true; - } - } - - /** - * @return the ifRange - */ - public boolean isIfRange() { - return ifRange; - } - - /** - * @param ifRange the ifRange to set - */ - public void setIfRange(boolean ifRange) { - this.ifRange = ifRange; - if ( ifRange ) { - enabled = true; - } - } - - /** - * Gets the cache context information (ETag, LastModified, predicates) from the Http request. - * @param request - * @return - */ - public static HTTPCacheContext createCacheContextFromRequest( HttpServletRequest request ) throws java.text.ParseException { - HTTPCacheContext context = new HTTPCacheContext(); - - String eTag = request.getHeader( "If-Match" ); - if ( eTag != null ) { - context.setETag( eTag ); - context.setIfMatch( true ); - } - eTag = request.getHeader( "If-None-Match" ); - if ( eTag != null ) { - context.setETag( eTag ); - context.setIfNoneMatch( true ); - } - String lastModifiedString = request.getHeader( "If-Modified-Since" ); - if ( lastModifiedString != null ) { - context.setLastModified( lastModifiedString ); - context.setIfModifiedSince( true ); - } - lastModifiedString = request.getHeader( "If-Unmodified-Since" ); - if ( lastModifiedString != null ) { - context.setLastModified( lastModifiedString ); - context.setIfUnmodifiedSince( true ); - } - lastModifiedString = request.getHeader( "If-Range" ); - if ( lastModifiedString != null ) { - context.setLastModified( lastModifiedString ); - context.setIfRange( true ); - } - return context; - } - - public String toString() { - final String PREDPREFIX = ", predicates="; - StringBuffer sb = new StringBuffer(PREDPREFIX); - if ( ifMatch || ifNoneMatch || ifModifiedSince || ifUnmodifiedSince || ifRange ) { - if ( ifMatch ) { - if ( sb.length() > PREDPREFIX.length() ) sb.append( ", "); - sb.append("If-Match"); - } - if ( ifNoneMatch ) { - if ( sb.length() > PREDPREFIX.length() ) sb.append( ", "); - sb.append("If-None-Match"); - } - if ( ifModifiedSince ) { - if ( sb.length() > PREDPREFIX.length() ) sb.append( ", "); - sb.append("If-Modified-Since"); - } - if ( ifUnmodifiedSince ) { - if ( sb.length() > PREDPREFIX.length() ) sb.append( ", "); - sb.append("If-UnModified-Since"); - } - if ( ifRange ) { - if ( sb.length() > PREDPREFIX.length() ) sb.append( ", "); - sb.append("If-Range"); - } - } else { - sb.append("null"); - } - - return "eTag=" + eTag + ", lastModified=" + lastModified - + sb.toString(); - } - -} diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPConstants.java b/sca-java-2.x/branches/2.0-Beta3/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPConstants.java deleted file mode 100644 index 056e7f5f54..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPConstants.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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.tuscany.sca.common.http; - -/** - * HTTP generic constants - * - * @version $Rev$ $Date$ - */ -public interface HTTPConstants { - public static final String CHARACTER_ENCODING_UTF8 = "UTF-8"; - - public static final String HTM = "htm"; - public static final String HTML = "html"; - public static final String JAVASCRIPT = "js"; - - public static final String HTML_CONTENT_TYPE = "text/html"; - public static final String JAVASCRIPT_CONTENT_TYPE = "text/javascript"; -} diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPContentTypeMapper.java b/sca-java-2.x/branches/2.0-Beta3/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPContentTypeMapper.java deleted file mode 100644 index 035e7c0fa6..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPContentTypeMapper.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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.tuscany.sca.common.http; - -import java.util.HashMap; -import java.util.Map; - -/** - * Utility class to provide default HTTP Content-Type header - * based on resource type - * - * @version $Rev$ $Date$ - */ -public class HTTPContentTypeMapper implements HTTPConstants{ - private static Map<String, String> contentTypeTable = new HashMap<String, String>(); - - static { - contentTypeTable.put(HTM, HTML_CONTENT_TYPE); - contentTypeTable.put(HTML, HTML_CONTENT_TYPE); - contentTypeTable.put(JAVASCRIPT, JAVASCRIPT_CONTENT_TYPE); - } - - /** - * Provided a resource path, identify default content-type based on the resource extension - * @param resourcePath - * @return - */ - public static String getContentType(String resourcePath) { - return contentTypeTable.get(getResourceType(resourcePath)); - } - - /** - * Utility function to calculate file type based on its extension - * Useful to map HTTP content-type based on file extension - * @param resource the resource/file name - * @return the resource type/extension - */ - private static String getResourceType(String resource) { - return resource.substring(resource.lastIndexOf(".") + 1); - } -} diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPContext.java b/sca-java-2.x/branches/2.0-Beta3/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPContext.java deleted file mode 100644 index 3324be6ef1..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPContext.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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.tuscany.sca.common.http; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * HTTP Context used as binding context in HTTP related bindings - * - * @version $Rev$ $Date$ - */ -public class HTTPContext { - private HttpServletRequest request; - private HttpServletResponse response; - - public HttpServletRequest getHttpRequest() { - return request; - } - public void setHttpRequest(HttpServletRequest request) { - this.request = request; - } - public HttpServletResponse getHttpResponse() { - return response; - } - public void setHttpResponse(HttpServletResponse response) { - this.response = response; - } -} diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPHeader.java b/sca-java-2.x/branches/2.0-Beta3/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPHeader.java deleted file mode 100644 index 63f62d1e5c..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPHeader.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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.tuscany.sca.common.http; - -/** - * Wrapper for HTTP header name/value pair - * - * @version $Rev$ $Date$ - */ - -public class HTTPHeader { - private String name; - private String value; - - public HTTPHeader() { - super(); - } - - public HTTPHeader(String name, String value) { - super(); - this.name = name; - this.value = value; - } - - /** - * Get header name - * @return the header name - */ - public String getName() { - return name; - } - - /** - * Set header value - * @param name the header name - */ - public void setName(String name) { - this.name = name; - } - - /** - * Get header value - * @return the header value - */ - public String getValue() { - return value; - } - - /** - * Set header value - * @param value the header value - */ - public void setValue(String value) { - this.value = value; - } - - @Override - public String toString() { - return "HTTPHeader [name=" + name + ", value=" + value + "]"; - } -} diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPUtils.java b/sca-java-2.x/branches/2.0-Beta3/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPUtils.java deleted file mode 100644 index 6ab6216522..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/HTTPUtils.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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.tuscany.sca.common.http; - -import java.math.BigInteger; -import java.security.MessageDigest; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * - * @tuscany.spi.extension.asclient - * - */ -public class HTTPUtils { - - /** - * Utility method to set common http headers and other stuff in a - * default http response. Applications / Extensions can then override and - * tweak as they see fit. - * - * @param response - */ - public static void prepareHTTPResponse(HttpServletResponse response) { - response.setDateHeader("Date", System.currentTimeMillis()); - } - - /** - * Calculate the relative request path taking in consideration if - * the application is running in a embedded webContatiner or from - * within a web application server host environment - * - * @param request The http request - * @return the relative path - */ - public static String getRequestPath(HttpServletRequest request) { - // Get the request path - String contextPath = request.getContextPath(); - String servletPath = request.getServletPath(); - String requestURI = request.getRequestURI(); - - int contextPathLength = contextPath.length(); - int servletPathLenght = servletPath.contains(contextPath) ? servletPath.length() - contextPath.length() : servletPath.length(); - - String requestPath = requestURI.substring(contextPathLength + servletPathLenght); - - return requestPath; - } - - /** - * Calculate the context root for an application taking in consideration if - * the application is running in a embedded webContatiner or from - * within a web application server host environment. - * - * In the case of webContainer the contextRoot will always be a empty string. - * - * @param request The http request - * @return the contextRoot - */ - public static String getContextRoot(HttpServletRequest request) { - // Get the request path - String contextPath = request.getContextPath(); - String requestURI = request.getRequestURI(); - - int contextPathLength = contextPath.length(); - - String contextRoot = requestURI.substring(0, contextPathLength); - - return contextRoot; - } - - /** - * Calculate the ETag using MD5 Hash Algorithm - * @param content the content to hash - * @return - */ - public static String calculateHashETag(byte[] content) { - String eTag = "invalid"; - try { - MessageDigest messageDigest = MessageDigest.getInstance("MD5"); - byte[] digest = messageDigest.digest(content); - BigInteger number = new BigInteger(1, digest); - StringBuffer sb = new StringBuffer('0'); - sb.append(number.toString(16)); - eTag = sb.toString(); - } catch(Exception e) { - //ignore, we will return random etag - eTag = Integer.toString((new java.util.Random()).nextInt(Integer.MAX_VALUE)); - } - return eTag; - } -} diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/ThreadHTTPContext.java b/sca-java-2.x/branches/2.0-Beta3/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/ThreadHTTPContext.java deleted file mode 100644 index fb1206f005..0000000000 --- a/sca-java-2.x/branches/2.0-Beta3/modules/common-http/src/main/java/org/apache/tuscany/sca/common/http/ThreadHTTPContext.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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.tuscany.sca.common.http; - -public class ThreadHTTPContext { - - private static final ThreadLocal<HTTPContext> CONTEXT = new ThreadLocal<HTTPContext>(); - - private ThreadHTTPContext() { - } - - public static HTTPContext setHTTPContext(HTTPContext context) { - HTTPContext old = CONTEXT.get(); - CONTEXT.set(context); - return old; - } - - public static HTTPContext getHTTPContext() { - return CONTEXT.get(); - } - - public static void removeHTTPContext() { - CONTEXT.remove(); - } -} |