1414package org .eclipse .birt .report .servlet ;
1515
1616import java .io .IOException ;
17-
18- import jakarta .servlet .ServletConfig ;
19- import jakarta .servlet .ServletException ;
20- import jakarta .servlet .ServletRequest ;
21- import jakarta .servlet .ServletResponse ;
22- import jakarta .servlet .http .HttpServlet ;
23- import jakarta .servlet .http .HttpServletRequest ;
24- import jakarta .servlet .http .HttpServletResponse ;
17+ import java .io .PrintWriter ;
18+ import java .io .StringWriter ;
19+ import java .nio .charset .StandardCharsets ;
20+ import java .util .Iterator ;
2521
2622import org .eclipse .birt .core .exception .BirtException ;
2723import org .eclipse .birt .report .IBirtConstants ;
24+ import org .eclipse .birt .report .context .BirtContext ;
2825import org .eclipse .birt .report .context .IContext ;
26+ import org .eclipse .birt .report .exception .ViewerException ;
2927import org .eclipse .birt .report .presentation .aggregation .IFragment ;
3028import org .eclipse .birt .report .resource .BirtResources ;
29+ import org .eclipse .birt .report .resource .ResourceConstants ;
30+ import org .eclipse .birt .report .service .BirtReportServiceFactory ;
3131import org .eclipse .birt .report .session .IViewingSession ;
3232import org .eclipse .birt .report .session .ViewingSessionUtil ;
33+ import org .eclipse .birt .report .soapengine .api .GetUpdatedObjects ;
34+ import org .eclipse .birt .report .soapengine .api .GetUpdatedObjectsResponse ;
35+ import org .eclipse .birt .report .soapengine .endpoint .BirtSoapBindingImpl ;
36+ import org .eclipse .birt .report .soapengine .endpoint .BirtSoapException ;
37+ import org .eclipse .birt .report .utility .BirtUtility ;
3338import org .eclipse .birt .report .utility .ParameterAccessor ;
3439
40+ import jakarta .servlet .ServletConfig ;
41+ import jakarta .servlet .ServletException ;
42+ import jakarta .servlet .ServletOutputStream ;
43+ import jakarta .servlet .ServletRequest ;
44+ import jakarta .servlet .ServletResponse ;
45+ import jakarta .servlet .http .HttpServlet ;
46+ import jakarta .servlet .http .HttpServletRequest ;
47+ import jakarta .servlet .http .HttpServletResponse ;
48+
3549/**
3650 * Jakarta-compatible BaseReportEngineServlet (Axis-free).
3751 */
@@ -52,16 +66,8 @@ public abstract class BaseReportEngineServlet extends HttpServlet {
5266
5367 protected abstract void __init (ServletConfig config );
5468
55- protected abstract boolean __authenticate (HttpServletRequest request , HttpServletResponse response );
56-
57- protected abstract IContext __getContext (HttpServletRequest request , HttpServletResponse response )
58- throws BirtException ;
59-
6069 protected abstract void __doGet (IContext context ) throws ServletException , IOException , BirtException ;
6170
62- protected abstract void __handleNonSoapException (HttpServletRequest request , HttpServletResponse response ,
63- Exception exception ) throws ServletException , IOException ;
64-
6571 /**
6672 * Check version.
6773 *
@@ -71,6 +77,30 @@ public static boolean isOpenSource() {
7177 return openSource ;
7278 }
7379
80+ /**
81+ * Init context.
82+ *
83+ * @param request incoming http request
84+ * @param response http response
85+ * @exception BirtException
86+ * @return IContext
87+ */
88+ protected IContext __getContext (HttpServletRequest request , HttpServletResponse response ) throws BirtException {
89+ BirtReportServiceFactory .getReportService ().setContext (getServletContext (), null );
90+ return new BirtContext (request , response );
91+ }
92+
93+ /**
94+ * Local authentication.
95+ *
96+ * @param request incoming http request
97+ * @param response http response
98+ * @return
99+ */
100+ protected boolean __authenticate (HttpServletRequest request , HttpServletResponse response ) {
101+ return true ;
102+ }
103+
74104 /**
75105 * Servlet init.
76106 *
@@ -100,6 +130,22 @@ public void service(ServletRequest req, ServletResponse res) throws ServletExcep
100130 super .service (req , res );
101131 }
102132
133+ /**
134+ * Process exception for non soap request.
135+ *
136+ * @param request incoming http request
137+ * @param response http response
138+ * @param exception
139+ * @throws ServletException
140+ * @throws IOException
141+ */
142+ public void __handleNonSoapException (HttpServletRequest request , HttpServletResponse response ,
143+ Exception exception ) throws ServletException , IOException {
144+ exception .printStackTrace ();
145+ response .setContentType ("text/html; charset=utf-8" ); //$NON-NLS-1$
146+ BirtUtility .appendErrorMessage (response .getOutputStream (), exception );
147+ }
148+
103149 /**
104150 * Handle HTTP GET method.
105151 *
@@ -130,9 +176,6 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro
130176 }
131177 } finally {
132178 session .unlock ();
133- if (!session .isLocked () && !__getContext (request , response ).getBean ().isShowParameterPage ()) {
134- session .invalidate ();
135- }
136179 }
137180 } catch (BirtException e ) {
138181 __handleNonSoapException (request , response , e );
@@ -150,6 +193,192 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro
150193 */
151194 @ Override
152195 public void doPost (HttpServletRequest request , HttpServletResponse response ) throws ServletException , IOException {
153- doGet (request , response );
196+ if (!__authenticate (request , response )) {
197+ return ;
198+ }
199+
200+ // create SOAP URL with post parameters
201+ StringBuilder builder = new StringBuilder ();
202+ Iterator it = request .getParameterMap ().keySet ().iterator ();
203+ while (it .hasNext ()) {
204+ String paramName = (String ) it .next ();
205+ if (paramName != null && paramName .startsWith ("__" )) //$NON-NLS-1$
206+ {
207+ String paramValue = ParameterAccessor .urlEncode (ParameterAccessor .getParameter (request , paramName ),
208+ ParameterAccessor .UTF_8_ENCODE );
209+ builder .append ("&" + paramName + "=" + paramValue ); //$NON-NLS-1$//$NON-NLS-2$
210+ }
211+ }
212+ String soapURL = request .getRequestURL ().toString ();
213+ if (ParameterAccessor .getBaseURL () != null ) {
214+ soapURL = ParameterAccessor .getBaseURL () + request .getContextPath () + request .getServletPath ();
215+ }
216+
217+ builder .deleteCharAt (0 );
218+ soapURL += "?" + builder .toString (); //$NON-NLS-1$
219+
220+ request .setAttribute ("SoapURL" , soapURL ); //$NON-NLS-1$
221+
222+ String requestType = request .getHeader (ParameterAccessor .HEADER_REQUEST_TYPE );
223+ boolean isSoapRequest = ParameterAccessor .HEADER_REQUEST_TYPE_SOAP .equalsIgnoreCase (requestType );
224+ // refresh the current BIRT viewing session by accessing it
225+ IViewingSession session ;
226+
227+ // init context
228+ IContext context = null ;
229+ try {
230+ session = ViewingSessionUtil .getSession (request );
231+ if (session == null && !isSoapRequest ) {
232+ if (ViewingSessionUtil .getSessionId (request ) == null ) {
233+ session = ViewingSessionUtil .createSession (request );
234+ } else {
235+ // if session id passed through the URL, it means this request
236+ // was expected to run using a session that has already expired
237+ throw new ViewerException (
238+ BirtResources .getMessage (ResourceConstants .GENERAL_ERROR_NO_VIEWING_SESSION ));
239+ }
240+ }
241+ context = __getContext (request , response );
242+ } catch (BirtException e ) {
243+ // throw exception
244+ __handleNonSoapException (request , response , e );
245+ return ;
246+ }
247+
248+ try {
249+ if (session != null ) {
250+ session .lock ();
251+ }
252+ __doPost (context );
253+
254+ if (isSoapRequest ) {
255+ soapService (request , response );
256+ } else {
257+ try {
258+ if (context .getBean ().getException () != null ) {
259+ __handleNonSoapException (request , response , context .getBean ().getException ());
260+ } else {
261+ __doGet (context );
262+ }
263+ } catch (BirtException e ) {
264+ __handleNonSoapException (request , response , e );
265+ }
266+ }
267+ } catch (BirtException e ) {
268+ e .printStackTrace ();
269+ } finally {
270+ if (session != null && !session .isExpired ()) {
271+ session .unlock ();
272+ }
273+ }
274+ }
275+
276+ /**
277+ * @param request
278+ * @param response
279+ */
280+ public void soapService (HttpServletRequest request , HttpServletResponse response ) {
281+
282+ try {
283+ GetUpdatedObjects requestObj = BirtSoapParser .parseGetUpdatedObjects (request );
284+
285+ BirtSoapBindingImpl binding = new BirtSoapBindingImpl ();
286+ GetUpdatedObjectsResponse responseObj = binding .getUpdatedObjects (requestObj );
287+ BirtSoapMarshaller .marshalResponse (responseObj , response );
288+ } catch (BirtSoapException e ) {
289+ // TODO Auto-generated catch block
290+ try {
291+ writeSoapFault (e .getFaultCode (), e .getMessage (), e , response );
292+ e .printStackTrace ();
293+ } catch (IOException e1 ) {
294+ // TODO Auto-generated catch block
295+ e1 .printStackTrace ();
296+ }
297+ } catch (Exception e ) {
298+ try {
299+ writeSoapFault ("Soap error" , e .getMessage (), e , response );
300+ e .printStackTrace ();
301+ } catch (IOException e1 ) {
302+ // TODO Auto-generated catch block
303+ e1 .printStackTrace ();
304+ }
305+ }
306+ }
307+ /**
308+ * @param context
309+ */
310+ public void __doPost (IContext context ) throws BirtException {
311+ // TODO Auto-generated method stub
312+
313+ }
314+
315+ private static String escape (String s ) {
316+ if (s == null ) {
317+ return "" ;
318+ }
319+
320+ StringBuilder out = new StringBuilder (s .length () + 16 );
321+ for (int i = 0 ; i < s .length (); i ++) {
322+ char c = s .charAt (i );
323+ switch (c ) {
324+ case '&' -> out .append ("&" );
325+ case '<' -> out .append ("<" );
326+ case '>' -> out .append (">" );
327+ case '"' -> out .append (""" );
328+ case '\'' -> out .append ("'" );
329+ default -> out .append (c );
330+ }
331+ }
332+ return out .toString ();
333+ }
334+
335+ private String getStackTrace (Throwable t ) {
336+ StringWriter sw = new StringWriter ();
337+ PrintWriter pw = new PrintWriter (sw );
338+ t .printStackTrace (pw );
339+ return sw .toString ();
340+ }
341+
342+ /**
343+ * @param faultCode
344+ * @param faultMessage
345+ * @param exception
346+ * @param resp
347+ * @throws IOException
348+ */
349+ public void writeSoapFault (String faultCode , String faultMessage , Throwable exception , HttpServletResponse resp )
350+ throws IOException {
351+
352+ resp .reset ();
353+ resp .setStatus (HttpServletResponse .SC_INTERNAL_SERVER_ERROR );
354+ resp .setContentType ("text/xml;charset=UTF-8" );
355+
356+ StringBuilder detailXml = new StringBuilder ();
357+ if (exception != null ) {
358+ // Rozdelíme stack trace na "chunks" podľa výnimiek
359+ Throwable current = exception ;
360+ while (current != null ) {
361+ StringWriter sw = new StringWriter ();
362+ PrintWriter pw = new PrintWriter (sw );
363+ current .printStackTrace (pw );
364+ pw .flush ();
365+ detailXml .append ("<string>" ).append (escape (sw .toString ())).append ("</string>" );
366+ current = current .getCause ();
367+ }
368+ }
369+
370+ String faultXml = "<?xml version=\" 1.0\" encoding=\" UTF-8\" ?>"
371+ + "<soapenv:Envelope xmlns:soapenv=\" http://schemas.xmlsoap.org/soap/envelope/\" >" + "<soapenv:Body>"
372+ + "<soapenv:Fault>" + "<faultcode>" + escape (faultCode ) + "</faultcode>" + "<faultstring>"
373+ + escape (faultMessage ) + "</faultstring>"
374+ + (detailXml .length () > 0 ? "<detail>" + detailXml + "</detail>" : "" ) + "</soapenv:Fault>"
375+ + "</soapenv:Body>" + "</soapenv:Envelope>" ;
376+
377+ byte [] bytes = faultXml .getBytes (StandardCharsets .UTF_8 );
378+ resp .setContentLength (bytes .length );
379+
380+ try (ServletOutputStream out = resp .getOutputStream ()) {
381+ out .write (bytes );
382+ }
154383 }
155384}
0 commit comments