/* $$ Clover has instrumented this file $$ */// Copyright 2004 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry.engine;
import java.io.IOException;
import javax.servlet.ServletException;
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.tapestry.IComponent;
import org.apache.tapestry.IExternalPage;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.Tapestry;
import org.apache.tapestry.request.ResponseOutputStream;
/**
* The external service enables external applications
* to reference Tapestry pages via a URL. Pages which can be referenced
* by the external service must implement the {@link IExternalPage}
* interface. The external service enables the bookmarking of pages.
*
* <p>
* The external service may also be used by the Tapestry JSP taglibrary
* ({@link org.apache.tapestry.jsp.ExternalURLTag} and {@link org.apache.tapestry.jsp.ExternalTag}).
*
* <p>
* You can try and second guess the URL format used by Tapestry.
* The default URL format for the external service is:
* <blockquote>
* <tt>http://localhost/app?service=external/<i>[Page Name]</i>&sp=[Param 0]&sp=[Param 1]...</tt>
* </blockquote>
* For example to view the "ViewCustomer" page the service parameters 5056 (customer ID) and
* 309 (company ID) the external service URL would be:
* <blockquote>
* <tt>http://localhost/myapp?service=external&context=<b>ViewCustomer</b>&sp=<b>5056</b>&sp=<b>302</b></tt>
* </blockquote>
* In this example external service will get a "ViewCustomer" page and invoke the
* {@link IExternalPage#activateExternalPage(Object[], IRequestCycle)} method with the parameters:
* Object[] { new Integer(5056), new Integer(302) }.
* <p>
* Note service parameters (sp) need to be prefixed by valid
* {@link org.apache.tapestry.util.io.DataSqueezerImpl} adaptor char. These adaptor chars are automatically provided in
* URL's created by the <tt>buildGesture()</tt> method. However if you hand coded an external
* service URL you will need to ensure valid prefix chars are present.
* <p>
* <table border="1" cellpadding="2">
* <tr>
* <th>Prefix char(s)</th><th>Mapped Java Type</th>
* </tr>
* <tr>
* <td> TF</td><td> boolean</td>
* </tr>
* <tr>
* <td> b</td><td> byte</td>
* </tr>
* <tr>
* <td> c</td><td> char</td>
* </tr>
* <tr>
* <td> d</td><td> double</td>
* </tr>
* <tr>
* <td> -0123456789</td><td> integer</td>
* </tr>
* <tr>
* <td> l</td><td> long</td>
* </tr>
* <tr>
* <td> S</td><td> String</td>
* </tr>
* <tr>
* <td> s</td><td> short</td>
* </tr>
* <tr>
* <td> other chars</td>
* <td> <tt>String</tt> without truncation of first char</td>
* </tr>
* <table>
* <p>
* <p>
* A good rule of thumb is to keep the information encoded in the URL short and simple, and restrict it
* to just Strings and Integers. Integers can be encoded as-is. Prefixing all Strings with the letter 'S'
* will ensure that they are decoded properly. Again, this is only relevant if an
* {@link org.apache.tapestry.IExternalPage} is being referenced from static HTML or JSP and the
* URL must be assembled in user code ... when the URL is generated by Tapestry, it is automatically
* created with the correct prefixes and encodings (as with any other service).
*
* @see org.apache.tapestry.IExternalPage
* @see org.apache.tapestry.jsp.ExternalTag
* @see org.apache.tapestry.jsp.ExternalURLTag
*
* @author Howard Lewis Ship
* @author Malcolm Edgar
* @since 2.2
*/
public class ExternalService extends AbstractService
{public static com.cortexeb.tools.clover.d __CLOVER_82_0 = com.cortexeb.tools.clover.aq.getRecorder(new char[] {67,58,92,119,111,114,107,115,112,97,99,101,92,106,97,107,97,114,116,97,45,116,97,112,101,115,116,114,121,92,102,114,97,109,101,119,111,114,107,92,116,97,114,103,101,116,92,99,108,111,118,101,114,45,100,98},1096998272901L);
public ILink getLink(IRequestCycle cycle, IComponent component, Object[] parameters)
{try { __CLOVER_82_0.M[473]++;
__CLOVER_82_0.S[2114]++;if ((((parameters == null || parameters.length == 0) && (++__CLOVER_82_0.CT[397] != 0)) || (++__CLOVER_82_0.CF[397] == 0))){
__CLOVER_82_0.S[2115]++;throw new ApplicationRuntimeException(
Tapestry.format("service-requires-parameters", Tapestry.EXTERNAL_SERVICE));}
__CLOVER_82_0.S[2116]++;String pageName = (String) parameters[0];
__CLOVER_82_0.S[2117]++;String[] context = new String[] { pageName };
__CLOVER_82_0.S[2118]++;Object[] pageParameters = new Object[parameters.length - 1];
__CLOVER_82_0.S[2119]++;System.arraycopy(parameters, 1, pageParameters, 0, parameters.length - 1);
__CLOVER_82_0.S[2120]++;return constructLink(cycle, Tapestry.EXTERNAL_SERVICE, context, pageParameters, true);
} finally { }}
public void service(
IEngineServiceView engine,
IRequestCycle cycle,
ResponseOutputStream output)
throws ServletException, IOException
{try { __CLOVER_82_0.M[474]++;
__CLOVER_82_0.S[2121]++;IExternalPage page = null;
__CLOVER_82_0.S[2122]++;String[] context = getServiceContext(cycle.getRequestContext());
__CLOVER_82_0.S[2123]++;if ((((context == null || context.length != 1) && (++__CLOVER_82_0.CT[398] != 0)) || (++__CLOVER_82_0.CF[398] == 0))){
__CLOVER_82_0.S[2124]++;throw new ApplicationRuntimeException(
Tapestry.format("service-single-context-parameter", Tapestry.EXTERNAL_SERVICE));}
__CLOVER_82_0.S[2125]++;String pageName = context[0];
__CLOVER_82_0.S[2126]++;try
{
__CLOVER_82_0.S[2127]++;page = (IExternalPage) cycle.getPage(pageName);
}
catch (ClassCastException ex)
{
__CLOVER_82_0.S[2128]++;throw new ApplicationRuntimeException(
Tapestry.format("ExternalService.page-not-compatible", pageName),
ex);
}
__CLOVER_82_0.S[2129]++;Object[] parameters = getParameters(cycle);
__CLOVER_82_0.S[2130]++;cycle.setServiceParameters(parameters);
__CLOVER_82_0.S[2131]++;cycle.activate(page);
__CLOVER_82_0.S[2132]++;page.activateExternalPage(parameters, cycle);
// Render the response.
__CLOVER_82_0.S[2133]++;engine.renderResponse(cycle, output);
} finally { }}
public String getName()
{try { __CLOVER_82_0.M[475]++;
__CLOVER_82_0.S[2134]++;return Tapestry.EXTERNAL_SERVICE;
} finally { }}
}