You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by ff...@apache.org on 2006/09/07 08:07:31 UTC
svn commit: r440987 - in /incubator/cxf/trunk:
api/src/main/java/org/apache/cxf/phase/
rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/
rt/core/src/main/java/org/apache/cxf/endpoint/
rt/core/src/main/java/org/apache/cxf/intercept...
Author: ffang
Date: Wed Sep 6 23:07:30 2006
New Revision: 440987
URL: http://svn.apache.org/viewvc?view=rev&rev=440987
Log:
[JIRA CXF-8] get jaxws Holder working, move Holder handle to jax-ws frontend
Added:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/JAXWSMethodInvoker.java (with props)
Modified:
incubator/cxf/trunk/api/src/main/java/org/apache/cxf/phase/PhaseInterceptorChain.java
incubator/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/ReadHeadersInterceptor.java
incubator/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/SoapOutInterceptor.java
incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/endpoint/ClientImpl.java
incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/BareOutInterceptor.java
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/EndpointImpl.java
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/EndpointInvocationHandler.java
incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/jaxws/HeaderClientServerTest.java
Modified: incubator/cxf/trunk/api/src/main/java/org/apache/cxf/phase/PhaseInterceptorChain.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/api/src/main/java/org/apache/cxf/phase/PhaseInterceptorChain.java?view=diff&rev=440987&r1=440986&r2=440987
==============================================================================
--- incubator/cxf/trunk/api/src/main/java/org/apache/cxf/phase/PhaseInterceptorChain.java (original)
+++ incubator/cxf/trunk/api/src/main/java/org/apache/cxf/phase/PhaseInterceptorChain.java Wed Sep 6 23:07:30 2006
@@ -125,7 +125,7 @@
while (state == State.EXECUTING && iterator.hasNext()) {
try {
Interceptor currentInterceptor = iterator.next();
- //System.out.println("Invoking handleMessage on interceptor " + currentInterceptor);
+
if (LOG.isLoggable(Level.FINE)) {
LOG.fine("Invoking handleMessage on interceptor " + currentInterceptor);
}
Modified: incubator/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/ReadHeadersInterceptor.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/ReadHeadersInterceptor.java?view=diff&rev=440987&r1=440986&r2=440987
==============================================================================
--- incubator/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/ReadHeadersInterceptor.java (original)
+++ incubator/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/ReadHeadersInterceptor.java Wed Sep 6 23:07:30 2006
@@ -35,7 +35,6 @@
import org.apache.cxf.binding.soap.SoapVersionFactory;
import org.apache.cxf.common.i18n.BundleUtils;
import org.apache.cxf.common.i18n.Message;
-//import org.apache.cxf.helpers.XMLUtils;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.staxutils.PartialXMLStreamReader;
import org.apache.cxf.staxutils.StaxUtils;
@@ -51,14 +50,7 @@
public void handleMessage(SoapMessage message) {
XMLStreamReader xmlReader = message.getContent(XMLStreamReader.class);
- /*XMLUtils.setIndention(4);
- System.out.println("the xml frag is ");
- try {
- System.out.println(XMLUtils.toString(StaxUtils.read(xmlReader)));
- } catch (XMLStreamException e1) {
- // TODO Auto-generated catch block
- e1.printStackTrace();
- }*/
+
if (xmlReader == null) {
InputStream in = (InputStream)message.getContent(InputStream.class);
Modified: incubator/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/SoapOutInterceptor.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/SoapOutInterceptor.java?view=diff&rev=440987&r1=440986&r2=440987
==============================================================================
--- incubator/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/SoapOutInterceptor.java (original)
+++ incubator/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/SoapOutInterceptor.java Wed Sep 6 23:07:30 2006
@@ -20,19 +20,15 @@
package org.apache.cxf.binding.soap.interceptor;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
-import javax.jws.WebParam;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
-import javax.xml.ws.Holder;
import org.w3c.dom.Element;
@@ -149,18 +145,11 @@
Object[] args = objs.toArray();
Object[] els = parts.toArray();
- if (args.length != els.length) {
- int holder = 0;
- if (args.length > els.length) {
- //detect Holder in params
- Method method = message.getContent(Method.class);
- holder = checkHolder(method);
- }
- if ((args.length - holder) != els.length) {
- message.setContent(Exception.class,
+ //should not have this assertion since jaxws-Holder may exist
+ /*if (args.length != els.length) {
+ message.setContent(Exception.class,
new RuntimeException("The number of arguments is not equal!"));
- }
- }
+ }*/
SoapVersion soapVersion = message.getVersion();
for (int idx = 0; idx < countParts; idx++) {
@@ -182,9 +171,6 @@
}
QName elName = ServiceModelUtil.getPartName(part);
DataWriter<XMLStreamWriter> dataWriter = getDataWriter(message);
- if (arg instanceof Holder) {
- arg = ((Holder)arg).value;
- }
dataWriter.write(arg, elName, xtw);
hasHeader = true;
@@ -203,25 +189,6 @@
}
- }
-
- private int checkHolder(Method method) {
- int holder = 0;
- if (method != null) {
-
- Annotation[][] paramAnnotations = method.getParameterAnnotations();
- for (int i = 0; i < paramAnnotations.length; i++) {
- Annotation[] annotation = paramAnnotations[i];
- for (int j = 0; j < annotation.length; j++) {
- if (annotation[j] instanceof WebParam
- && (((WebParam)annotation[j]).mode().equals(WebParam.Mode.OUT)
- || ((WebParam)annotation[j]).mode().equals(WebParam.Mode.INOUT))) {
- holder++;
- }
- }
- }
- }
- return holder;
}
protected boolean isRequestor(Message message) {
Modified: incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/endpoint/ClientImpl.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/endpoint/ClientImpl.java?view=diff&rev=440987&r1=440986&r2=440987
==============================================================================
--- incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/endpoint/ClientImpl.java (original)
+++ incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/endpoint/ClientImpl.java Wed Sep 6 23:07:30 2006
@@ -21,9 +21,6 @@
import java.io.IOException;
import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -31,9 +28,6 @@
import java.util.logging.Level;
import java.util.logging.Logger;
-import javax.xml.ws.Holder;
-
-
import org.apache.cxf.Bus;
import org.apache.cxf.BusException;
import org.apache.cxf.binding.Binding;
@@ -166,12 +160,8 @@
throw new RuntimeException(inMsg.getContent(Exception.class));
}
- // handle Holder case
- List<Object> retList = new ArrayList<Object>();
- if (message.getContent(Method.class) != null) {
- handleHolderReturn(params, message, inMsg, retList);
- return retList.toArray();
- }
+
+
return inMsg.getContent(List.class).toArray();
}
}
@@ -193,54 +183,7 @@
}
}
- private void handleHolderReturn(Object[] params, Message message, Message inMsg, List<Object> retList) {
- Object[] rawRet = inMsg.getContent(List.class).toArray();
-
- int idx = 0;
- Method method = message.getContent(Method.class);
- if (method == null) {
- return;
- }
- if (!((Class)method.getReturnType()).getName().equals("void")) {
- retList.add(rawRet[0]);
- idx++;
- }
- int holderStartIndex = 0;
- Type[] para = method.getGenericParameterTypes();
- for (int i = 0; i < para.length; i++) {
- if (para[i] instanceof ParameterizedType) {
- ParameterizedType paramType = (ParameterizedType)para[i];
- if (((Class)paramType.getRawType()).getName().equals("javax.xml.ws.Holder")) {
- break;
- } else {
- holderStartIndex++;
- }
- } else {
- holderStartIndex++;
- }
- }
-
- for (int i = idx; i < rawRet.length; i++, holderStartIndex++) {
- try {
- ((Holder)params[holderStartIndex]).getClass().getField(
- "value").set(params[holderStartIndex], rawRet[i]);
- } catch (IllegalArgumentException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (SecurityException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (NoSuchFieldException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
-
- }
- }
-
+
public void onMessage(Message message) {
Modified: incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/BareOutInterceptor.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/BareOutInterceptor.java?view=diff&rev=440987&r1=440986&r2=440987
==============================================================================
--- incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/BareOutInterceptor.java (original)
+++ incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/BareOutInterceptor.java Wed Sep 6 23:07:30 2006
@@ -18,12 +18,8 @@
*/
package org.apache.cxf.interceptor;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
import java.util.List;
-import javax.jws.WebParam;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamWriter;
@@ -67,18 +63,12 @@
Object[] args = objs.toArray();
Object[] els = parts.toArray();
- if (args.length != els.length) {
- int holder = 0;
- if (args.length > els.length) {
- //detect Holder in params
- Method method = message.getContent(Method.class);
- holder = checkHolder(method);
- }
- if ((args.length - holder) != els.length) {
- message.setContent(Exception.class,
- new RuntimeException("The number of arguments is not equal!"));
- }
- }
+ //should not have this assertion since jaxws-Holder may exist
+ /*if (args.length != els.length) {
+ message.setContent(Exception.class,
+ new RuntimeException("The number of arguments is not equal!"));
+ }*/
+
XMLStreamWriter xmlWriter = getXMLStreamWriter(message);
for (int idx = 0; idx < countParts; idx++) {
Object arg = args[idx];
@@ -93,22 +83,5 @@
}
}
- private int checkHolder(Method method) {
- int holder = 0;
- if (method != null) {
-
- Annotation[][] paramAnnotations = method.getParameterAnnotations();
- for (int i = 0; i < paramAnnotations.length; i++) {
- Annotation[] annotation = paramAnnotations[i];
- for (int j = 0; j < annotation.length; j++) {
- if (annotation[j] instanceof WebParam
- && (((WebParam)annotation[j]).mode().equals(WebParam.Mode.OUT)
- || ((WebParam)annotation[j]).mode().equals(WebParam.Mode.INOUT))) {
- holder++;
- }
- }
- }
- }
- return holder;
- }
+
}
Modified: incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/EndpointImpl.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/EndpointImpl.java?view=diff&rev=440987&r1=440986&r2=440987
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/EndpointImpl.java (original)
+++ incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/EndpointImpl.java Wed Sep 6 23:07:30 2006
@@ -40,7 +40,6 @@
import org.apache.cxf.jaxws.support.JaxwsEndpointImpl;
import org.apache.cxf.jaxws.support.JaxwsImplementorInfo;
import org.apache.cxf.service.Service;
-import org.apache.cxf.service.invoker.SimpleMethodInvoker;
import org.apache.cxf.service.model.EndpointInfo;
import org.apache.cxf.transport.ChainInitiationObserver;
import org.apache.cxf.transport.MessageObserver;
@@ -79,8 +78,7 @@
if (implInfo.isWebServiceProvider()) {
service.setInvoker(new ProviderInvoker((Provider<?>)i));
} else {
- //TODO - need a jaxws specific invoker for holders and such
- service.setInvoker(new SimpleMethodInvoker(i));
+ service.setInvoker(new JAXWSMethodInvoker(i));
}
// TODO: use bindigURI
endpoint = new JaxwsEndpointImpl(bus, service, ei);
Modified: incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/EndpointInvocationHandler.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/EndpointInvocationHandler.java?view=diff&rev=440987&r1=440986&r2=440987
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/EndpointInvocationHandler.java (original)
+++ incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/EndpointInvocationHandler.java Wed Sep 6 23:07:30 2006
@@ -21,7 +21,11 @@
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;
@@ -30,6 +34,7 @@
import javax.xml.namespace.QName;
import javax.xml.ws.Binding;
import javax.xml.ws.BindingProvider;
+import javax.xml.ws.Holder;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;
import javax.xml.ws.WebServiceException;
@@ -77,17 +82,40 @@
throw new WebServiceException(msg.toString());
}
- // REVISIT - Holder objects, etc...
+
Object[] params = args;
if (null == params) {
params = new Object[0];
}
+
+
+ Object[] paramsWithOutHolder = handleHolder(params);
Map<String, Object> context = new HashMap<String, Object>();
context.put(org.apache.cxf.message.Message.METHOD, method);
- Object obj[] = client.invoke(oi, params, context);
-
- return obj == null || obj.length == 0 ? null : obj[0];
+ Object rawRet[] = client.invoke(oi, paramsWithOutHolder, context);
+
+ if (rawRet != null && rawRet.length != 0) {
+ List<Object> retList = new ArrayList<Object>();
+ handleHolderReturn(params, method, rawRet, retList);
+ Object[] obj = retList.toArray();
+ return obj == null || obj.length == 0 ? null : obj[0];
+ } else {
+ return null;
+ }
+ }
+
+ private Object[] handleHolder(Object[] params) {
+ //get value out of Holder
+ Object[] ret = new Object[params.length];
+ for (int i = 0; i < params.length; i++) {
+ if (params[i] instanceof Holder) {
+ ret[i] = ((Holder)params[i]).value;
+ } else {
+ ret[i] = params[i];
+ }
+ }
+ return ret;
}
BindingOperationInfo getOperationInfo(Object proxy, Method method) {
@@ -142,6 +170,51 @@
}
return boi;
}
+
+
+ private void handleHolderReturn(Object[] params, Method method, Object[] rawRet, List<Object> retList) {
+
+ int idx = 0;
+
+ if (method == null) {
+ return;
+ }
+ if (!((Class)method.getReturnType()).getName().equals("void")) {
+ retList.add(rawRet[0]);
+ idx++;
+ }
+ int holderStartIndex = 0;
+ Type[] para = method.getGenericParameterTypes();
+ for (int i = 0; i < para.length; i++) {
+ if (para[i] instanceof ParameterizedType) {
+ ParameterizedType paramType = (ParameterizedType)para[i];
+ if (((Class)paramType.getRawType()).getName().equals("javax.xml.ws.Holder")) {
+ break;
+ } else {
+ holderStartIndex++;
+ }
+ } else {
+ holderStartIndex++;
+ }
+ }
+
+ for (int i = idx; i < rawRet.length; i++, holderStartIndex++) {
+ try {
+ ((Holder)params[holderStartIndex]).getClass().getField(
+ "value").set(params[holderStartIndex], rawRet[i]);
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ } catch (NoSuchFieldException e) {
+ e.printStackTrace();
+ }
+
+ }
+ }
+
protected Class getResponseWrapper(Method selected) throws ClassNotFoundException {
ResponseWrapper rw = selected.getAnnotation(ResponseWrapper.class);
Added: incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/JAXWSMethodInvoker.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/JAXWSMethodInvoker.java?view=auto&rev=440987
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/JAXWSMethodInvoker.java (added)
+++ incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/JAXWSMethodInvoker.java Wed Sep 6 23:07:30 2006
@@ -0,0 +1,115 @@
+/**
+ * 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.cxf.jaxws;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.xml.ws.Holder;
+
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.message.Exchange;
+import org.apache.cxf.service.invoker.Invoker;
+import org.apache.cxf.service.model.BindingOperationInfo;
+
+public class JAXWSMethodInvoker implements Invoker {
+
+ private Object bean;
+
+ public JAXWSMethodInvoker(Object bean) {
+ super();
+ this.bean = bean;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Object invoke(Exchange exchange, Object o) {
+ BindingOperationInfo bop = exchange.get(BindingOperationInfo.class);
+
+
+ Method m = (Method)bop.getOperationInfo().getProperty(Method.class.getName());
+ List<Object> params = (List<Object>) o;
+
+ checkHolder(m, params, exchange);
+ Object res;
+ try {
+ Object[] paramArray = params.toArray();
+ res = m.invoke(bean, paramArray);
+ if (exchange.isOneWay()) {
+ return null;
+ }
+ List<Object> retList = new ArrayList<Object>();
+ if (!((Class)m.getReturnType()).getName().equals("void")) {
+ retList.add(res);
+ }
+ for (int i = 0; i < paramArray.length; i++) {
+ if (paramArray[i] instanceof Holder) {
+ retList.add(((Holder)paramArray[i]).value);
+ }
+ }
+ return Arrays.asList(retList.toArray());
+ } catch (Exception e) {
+ throw new Fault(e);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private void checkHolder(Method method, List<Object> params, Exchange exchange) {
+ if (method != null) {
+
+ Type[] para = method.getGenericParameterTypes();
+ for (int i = 0; i < para.length; i++) {
+ if (para[i] instanceof ParameterizedType) {
+ Object param = null;
+ ParameterizedType paramType = (ParameterizedType)para[i];
+ if (((Class)paramType.getRawType()).getName().equals("javax.xml.ws.Holder")) {
+
+ try {
+ param = new Holder(
+ ((Class)paramType.getActualTypeArguments()[0]).newInstance());
+ } catch (InstantiationException e) {
+ throw new Fault(e);
+ } catch (IllegalAccessException e) {
+ throw new Fault(e);
+ }
+ if (i >= params.size()) {
+ params.add(param);
+ } else {
+ params.set(i, new Holder(params.get(i)));
+ }
+
+ }
+
+
+ }
+ }
+
+ }
+
+ }
+
+
+
+}
Propchange: incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/JAXWSMethodInvoker.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/JAXWSMethodInvoker.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/jaxws/HeaderClientServerTest.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/jaxws/HeaderClientServerTest.java?view=diff&rev=440987&r1=440986&r2=440987
==============================================================================
--- incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/jaxws/HeaderClientServerTest.java (original)
+++ incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/jaxws/HeaderClientServerTest.java Wed Sep 6 23:07:30 2006
@@ -87,7 +87,7 @@
assertTrue("server did not launch correctly", launchServer(MyServer.class));
}
};
-
+
}