List of usage examples for javax.servlet.http HttpServletRequest getClass
@HotSpotIntrinsicCandidate public final native Class<?> getClass();
From source file:it.classhidra.core.controller.bsController.java
public static i_action getActionInstance(String id_action, String id_call, HttpServletRequest request, HttpServletResponse response) throws bsControllerException, ServletException, UnavailableException { boolean cloned = (request.getParameter(CONST_ID_EXEC_TYPE) == null) ? false : request.getParameter(CONST_ID_EXEC_TYPE).equalsIgnoreCase(CONST_ID_EXEC_TYPE_CLONED); i_action action_instance = getAction_config().actionFactory(id_action, request.getSession(), request.getSession().getServletContext()); i_bean bean_instance = getCurrentForm(id_action, request); if (bean_instance == null) { info_bean iBean = (info_bean) getAction_config().get_beans() .get(action_instance.get_infoaction().getName()); if (action_instance instanceof i_bean && (action_instance.get_infoaction().getName().equals("") || (iBean != null && action_instance.get_infoaction().getType().equals(iBean.getType())))) bean_instance = (i_bean) action_instance; else/*from w w w . j ava 2 s . co m*/ bean_instance = getAction_config().beanFactory(action_instance.get_infoaction().getName(), request.getSession(), request.getSession().getServletContext(), action_instance); if (bean_instance != null) { if (bean_instance.getCurrent_auth() == null || action_instance.get_infoaction().getMemoryInSession().equalsIgnoreCase("true")) bean_instance.setCurrent_auth(bsController.checkAuth_init(request)); bean_instance.reimposta(); } //Modifica 20100521 WARNING if (cloned) { try { action_instance.onPreSet_bean(); action_instance.set_bean((i_bean) bean_instance.clone()); action_instance.onPostSet_bean(); } catch (Exception e) { action_instance.onPreSet_bean(); action_instance.set_bean(bean_instance); action_instance.onPostSet_bean(); } } else { action_instance.onPreSet_bean(); action_instance.set_bean(bean_instance); action_instance.onPostSet_bean(); } } else { if (bean_instance.getCurrent_auth() == null || action_instance.get_infoaction().getMemoryInSession().equalsIgnoreCase("true")) bean_instance.setCurrent_auth(bsController.checkAuth_init(request)); if (action_instance instanceof i_bean && (action_instance.get_infoaction().getName().equals("") || bean_instance.getClass().getName().equals(action_instance.getClass().getName()))) { if (cloned) { try { action_instance = (i_action) util_cloner.clone(bean_instance); } catch (Exception e) { action_instance = (i_action) bean_instance; } } else action_instance = (i_action) bean_instance; } else { if (cloned) { try { action_instance.onPreSet_bean(); action_instance.set_bean((i_bean) util_cloner.clone(bean_instance)); action_instance.onPostSet_bean(); } catch (Exception e) { action_instance.onPreSet_bean(); action_instance.set_bean(bean_instance); action_instance.onPostSet_bean(); } } else { action_instance.onPreSet_bean(); action_instance.set_bean(bean_instance); action_instance.onPostSet_bean(); } } } action_instance.onPreInit(request, response); action_instance.init(request, response); action_instance.onPostInit(request, response); info_call iCall = null; Method iCallMethod = null; if (id_call != null) { try { iCall = (info_call) action_instance.get_infoaction().get_calls().get(id_call); if (iCall == null) { Object[] method_call = action_instance.getMethodAndCall(id_call); if (method_call != null) { iCallMethod = (Method) method_call[0]; iCall = (info_call) method_call[1]; action_instance.get_infoaction().get_calls().put(iCall.getName(), iCall); } /* iCallMethod = action_instance.getMethodForCall(id_call); if(iCallMethod!=null){ iCall = new info_call(); iCall.setMethod(iCallMethod.getName()); action_instance.get_infoaction().get_calls().put(iCall.getName(),iCall); } */ } else { try { iCallMethod = util_reflect.getMethodName(action_instance, iCall.getMethod(), new Class[] { request.getClass(), response.getClass() }); } catch (Exception em) { } } } catch (Exception ex) { new bsControllerException(ex, iStub.log_ERROR); } catch (Throwable th) { new bsControllerException(th, iStub.log_ERROR); } } if (iCall != null && iCall.getNavigated().equalsIgnoreCase("false")) { } else setInfoNav_CurrentForm(action_instance, request); // ACTIONSEVICE redirects current_redirect = null; if (id_call == null) { if (action_instance.get_infoaction().getSyncro().equalsIgnoreCase("true")) { action_instance.onPreSyncroservice(request, response); current_redirect = action_instance.syncroservice(request, response); action_instance.onPostSyncroservice(current_redirect, request, response); } else { current_redirect = action_instance.actionservice(request, response); action_instance.onPostActionservice(current_redirect, request, response); } } else { try { if (iCallMethod != null) { action_instance.onPreActionCall(id_call, request, response); current_redirect = (redirects) util_reflect.getValue(action_instance, iCallMethod, new Object[] { request, response }); action_instance.onPostActionCall(current_redirect, id_call, request, response); } } catch (Exception ex) { new bsControllerException(ex, iStub.log_ERROR); } catch (Throwable th) { new bsControllerException(th, iStub.log_ERROR); } } // Mod 20130923 -- // if(current_redirect==null) return null; action_instance.onPreSetCurrent_redirect(); action_instance.setCurrent_redirect(current_redirect); action_instance.onPostSetCurrent_redirect(); if (iCall != null && iCall.getNavigated().equalsIgnoreCase("false")) { try { i_bean form = action_instance.get_bean(); if (form.get_infoaction().getMemoryInSession().equalsIgnoreCase("true")) { HashMap fromSession = null; fromSession = (HashMap) request.getSession() .getAttribute(bsConstants.CONST_BEAN_$ONLYINSSESSION); if (fromSession == null) { fromSession = new HashMap(); request.getSession().setAttribute(bsConstants.CONST_BEAN_$ONLYINSSESSION, fromSession); } if (form != null) form.onAddToSession(); fromSession.put(form.get_infobean().getName(), form); } } catch (Exception e) { } } else setCurrentForm(action_instance, request); return action_instance; }
From source file:org.apache.cocoon.servletservice.DispatcherServlet.java
protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { final Map mountableServlets = getBlockServletMap(); String path = req.getPathInfo(); if (path == null) { path = ""; }/*from w ww .j a v a 2 s. c om*/ // find the servlet which mount path is the longest prefix of the path info int index = path.length(); Servlet servlet = null; while (servlet == null && index != -1) { path = path.substring(0, index); servlet = (Servlet) mountableServlets.get(path); index = path.lastIndexOf('/'); } //case when servlet is mounted at "/" must be handled separately servlet = servlet == null ? (Servlet) mountableServlets.get("/") : servlet; if (servlet == null) { String message = "No block for " + req.getPathInfo(); res.sendError(HttpServletResponse.SC_NOT_FOUND, message); this.logger.info(message); return; } // Create a dynamic proxy class that overwrites the getServletPath and // getPathInfo methods to provide reasonable values in the called servlet // the dynamic proxy implements all interfaces of the original request HttpServletRequest request = (HttpServletRequest) Proxy.newProxyInstance(req.getClass().getClassLoader(), getInterfaces(req.getClass()), new DynamicProxyRequestHandler(req, path)); if (this.logger.isDebugEnabled()) { this.logger.debug("DispatcherServlet: service servlet=" + servlet + " mountPath=" + path + " servletPath=" + request.getServletPath() + " pathInfo=" + request.getPathInfo()); } servlet.service(request, res); }
From source file:org.dbflute.saflute.web.servlet.filter.RequestLoggingFilter.java
protected void buildRequestInfo(StringBuilder sb, HttpServletRequest request, HttpServletResponse response, boolean showResponse) { sb.append("Request class=" + request.getClass().getName()); sb.append(", RequestedSessionId=").append(request.getRequestedSessionId()); sb.append(LF).append(IND);/* ww w . ja v a2s . c o m*/ sb.append(", REQUEST_URI=").append(request.getRequestURI()); sb.append(", SERVLET_PATH=").append(request.getServletPath()); sb.append(", CharacterEncoding=" + request.getCharacterEncoding()); sb.append(", ContentLength=").append(request.getContentLength()); sb.append(LF).append(IND); sb.append(", ContentType=").append(request.getContentType()); sb.append(", Locale=").append(request.getLocale()); sb.append(", Locales="); final Enumeration<?> locales = request.getLocales(); boolean first = true; while (locales.hasMoreElements()) { final Locale locale = (Locale) locales.nextElement(); if (first) { first = false; } else { sb.append(", "); } sb.append(locale.toString()); } sb.append(", Scheme=").append(request.getScheme()); sb.append(", isSecure=").append(request.isSecure()); sb.append(LF).append(IND); sb.append(", SERVER_PROTOCOL=").append(request.getProtocol()); sb.append(", REMOTE_ADDR=").append(request.getRemoteAddr()); sb.append(", REMOTE_HOST=").append(request.getRemoteHost()); sb.append(", SERVER_NAME=").append(request.getServerName()); sb.append(", SERVER_PORT=").append(request.getServerPort()); sb.append(LF).append(IND); sb.append(", ContextPath=").append(request.getContextPath()); sb.append(", REQUEST_METHOD=").append(request.getMethod()); sb.append(", PathInfo=").append(request.getPathInfo()); sb.append(", RemoteUser=").append(request.getRemoteUser()); sb.append(LF).append(IND); sb.append(", REQUEST_URL=").append(request.getRequestURL()); sb.append(LF).append(IND); sb.append(", QUERY_STRING=").append(request.getQueryString()); if (showResponse) { sb.append(LF).append(IND); buildResponseInfo(sb, request, response); } sb.append(LF); buildRequestHeaders(sb, request); buildRequestParameters(sb, request); buildCookies(sb, request); buildRequestAttributes(sb, request); buildSessionAttributes(sb, request); }
From source file:org.infoglue.deliver.portal.information.RenderRequestIG.java
public RenderRequestIG(PortletWindow portletWindow, HttpServletRequest servletRequest) { super(portletWindow, servletRequest); this.log = ((LogService) PortletContainerServices.get(LogService.class)).getLogger(getClass()); log.debug("Original servletRequest of type [" + servletRequest.getClass().getName() + "]"); origRequest = servletRequest;//w ww .j a v a 2 s . com }
From source file:org.oclc.oai.server.OAIHandler.java
/** * Override to do any prequalification; return false if the response should be returned immediately, without further * action.// w w w. j a v a 2 s . c o m * * @param request * @param response * @return false=return immediately, true=continue */ protected boolean filterRequest(HttpServletRequest request, HttpServletResponse response) { request.getClass(); // so they are used response.getClass(); return true; }
From source file:org.openmrs.module.sync.web.controller.ImportListController.java
@Override protected ModelAndView processFormSubmission(HttpServletRequest request, HttpServletResponse response, Object obj, BindException errors) throws Exception { log.info("***********************************************************\n"); log.info("Inside SynchronizationImportListController"); // just fail fast if in the midst of refreshing the context, as this was causing issues, see SYNC-318 if (Context.isRefreshingContext()) { return null; }//from www. j av a2 s. c o m // There are 3 ways to come to this point, so we'll handle all of them: // 1) uploading a file (results in a file attachment as response) // 2) posting data to page (results in pure XML output) // 3) remote connection (with username + password, also posting data) (results in pure XML) // none of these result in user-friendly - so no comfy, user-friendly stuff needed here //outputing statistics: debug only! log.info("HttpServletRequest INFO:"); log.info("ContentType: " + request.getContentType()); log.info("CharacterEncoding: " + request.getCharacterEncoding()); log.info("ContentLength: " + request.getContentLength()); log.info("checksum: " + request.getParameter("checksum")); log.info("syncData: " + request.getParameter("syncData")); log.info("syncDataResponse: " + request.getParameter("syncDataResponse")); long checksum = 0; Integer serverId = 0; boolean isResponse = false; boolean isUpload = false; boolean useCompression = false; String contents = ""; String username = ""; String password = ""; //file-based upload, and multi-part form submission if (request instanceof MultipartHttpServletRequest) { log.info("Processing contents of syncDataFile multipart request parameter"); MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; serverId = ServletRequestUtils.getIntParameter(multipartRequest, "serverId", 0); isResponse = ServletRequestUtils.getBooleanParameter(multipartRequest, "isResponse", false); useCompression = ServletRequestUtils.getBooleanParameter(multipartRequest, "compressed", false); isUpload = ServletRequestUtils.getBooleanParameter(multipartRequest, "upload", false); username = ServletRequestUtils.getStringParameter(multipartRequest, "username", ""); password = ServletRequestUtils.getStringParameter(multipartRequest, "password", ""); log.info("Request class: " + request.getClass()); log.info("serverId: " + serverId); log.info("upload = " + isUpload); log.info("compressed = " + useCompression); log.info("response = " + isResponse); log.info("username = " + username); log.info("Request content length: " + request.getContentLength()); MultipartFile multipartFile = multipartRequest.getFile("syncDataFile"); if (multipartFile != null && !multipartFile.isEmpty()) { InputStream inputStream = null; try { // Decompress content in file ConnectionResponse syncResponse = new ConnectionResponse( new ByteArrayInputStream(multipartFile.getBytes()), useCompression); log.info("Content to decompress: " + multipartFile.getBytes()); log.info("Content received: " + syncResponse.getResponsePayload()); log.info("Decompression Checksum: " + syncResponse.getChecksum()); contents = syncResponse.getResponsePayload(); checksum = syncResponse.getChecksum(); log.info("Final content: " + contents); } catch (Exception e) { log.warn("Unable to read in sync data file", e); } finally { IOUtils.closeQuietly(inputStream); } } } else { log.debug("seems we DO NOT have a file object"); } // prepare to process the input: contents now contains decompressed request ready to be processed SyncTransmissionResponse str = new SyncTransmissionResponse(); str.setErrorMessage(SyncConstants.ERROR_TX_NOT_UNDERSTOOD); str.setFileName(SyncConstants.FILENAME_TX_NOT_UNDERSTOOD); str.setUuid(SyncConstants.UUID_UNKNOWN); str.setSyncSourceUuid(SyncConstants.UUID_UNKNOWN); str.setSyncTargetUuid(SyncConstants.UUID_UNKNOWN); str.setState(SyncTransmissionState.TRANSMISSION_NOT_UNDERSTOOD); str.setTimestamp(new Date()); //set the timestamp of the response if (log.isInfoEnabled()) { log.info("CONTENT IN IMPORT CONTROLLER: " + contents); } //if no content, nothing to process just send back response if (contents == null || contents.length() < 0) { log.info("returning from ingest: nothing to process."); this.sendResponse(str, isUpload, response); return null; } // if this is option 3 (posting from remote server), we need to authenticate if (!Context.isAuthenticated()) { try { Context.authenticate(username, password); } catch (Exception e) { } } // Could not authenticate user: send back error if (!Context.isAuthenticated()) { str.setErrorMessage(SyncConstants.ERROR_AUTH_FAILED); str.setFileName(SyncConstants.FILENAME_AUTH_FAILED); str.setState(SyncTransmissionState.AUTH_FAILED); this.sendResponse(str, isUpload, response); return null; } //Fill-in the server uuid for the response: since request was authenticated we can start letting callers //know about us str.setSyncTargetUuid(Context.getService(SyncService.class).getServerUuid()); //Checksum check before doing anything at all: on unreliable networks we can get seemingly //valid HTTP POST but content is messed up, defend against it with custom checksums long checksumReceived = ServletRequestUtils.getLongParameter(request, "checksum", -1); log.info("checksum value received in POST: " + checksumReceived); log.info("checksum value of payload: " + checksum); log.info("SIZE of payload: " + contents.length()); if (checksumReceived > 0 && (checksumReceived != checksum)) { log.error("ERROR: FAILED CHECKSUM!"); str.setState(SyncTransmissionState.TRANSMISSION_NOT_UNDERSTOOD); this.sendResponse(str, isUpload, response); return null; } //Test message. Test message was sent (i.e. using 'test connection' button on server screen) //just send empty acknowledgment if (SyncConstants.TEST_MESSAGE.equals(contents)) { str.setErrorMessage(""); str.setState(SyncTransmissionState.OK); str.setUuid(""); str.setFileName(SyncConstants.FILENAME_TEST); this.sendResponse(str, isUpload, response); return null; } if (SyncConstants.CLONE_MESSAGE.equals(contents)) { try { log.info("CLONE MESSAGE RECEIVED, TRYING TO CLONE THE DB"); File file = Context.getService(SyncService.class).generateDataFile(); StringWriter writer = new StringWriter(); IOUtils.copy(new FileInputStream(file), writer); this.sendCloneResponse(writer.toString(), response, false); boolean clonedDBLog = Boolean.parseBoolean(Context.getAdministrationService() .getGlobalProperty(SyncConstants.PROPERTY_SYNC_CLONED_DATABASE_LOG_ENABLED, "true")); if (!clonedDBLog) { file.delete(); } } catch (Exception ex) { log.warn(ex.toString()); ex.printStackTrace(); } return null; } /************************************************************************************************************************* * This is a real transmission: - user was properly authenticated - checksums match - it is * not a test transmission Start processing! 1. Deserialize what was sent; it can be either * SyncTransmssion, or SyncTransmissionResponse 2. If it is a response, *************************************************************************************************************************/ SyncTransmission st = null; if (!isResponse) { //this is not 'response' to something we sent out; thus the contents should contain plan SyncTransmission try { log.info("xml to sync transmission with contents: " + contents); st = SyncDeserializer.xmlToSyncTransmission(contents); } catch (Exception e) { log.error("Unable to deserialize the following: " + contents, e); str.setErrorMessage("Unable to deserialize transmission contents into SyncTansmission."); str.setState(SyncTransmissionState.TRANSMISSION_NOT_UNDERSTOOD); this.sendResponse(str, isUpload, response); return null; } } else { log.info("Processing a response, not a transmission"); SyncTransmissionResponse priorResponse = null; try { // this is the confirmation of receipt of previous transmission priorResponse = SyncDeserializer.xmlToSyncTransmissionResponse(contents); log.info("This is a response from a previous transmission. Uuid is: " + priorResponse.getUuid()); } catch (Exception e) { log.error("Unable to deserialize the following: " + contents, e); str.setErrorMessage("Unable to deserialize transmission contents into SyncTransmissionResponse."); str.setState(SyncTransmissionState.TRANSMISSION_NOT_UNDERSTOOD); this.sendResponse(str, isUpload, response); return null; } // figure out where this came from: // for responses, the target ID contains the server that generated the response String sourceUuid = priorResponse.getSyncTargetUuid(); log.info("SyncTransmissionResponse has a sourceUuid of " + sourceUuid); RemoteServer origin = Context.getService(SyncService.class).getRemoteServer(sourceUuid); if (origin == null) { log.error("Source server not registered locally. Unable to find source server by uuid: " + sourceUuid); str.setErrorMessage( "Source server not registered locally. Unable to find source server by uuid " + sourceUuid); str.setState(SyncTransmissionState.INVALID_SERVER); this.sendResponse(str, isUpload, response); return null; } else { log.info("Found source server by uuid: " + sourceUuid + " = " + origin.getNickname()); log.info("Source server is " + origin.getNickname()); } if (priorResponse == null) { } // process response that was sent to us; the sync response normally contains: //a) results of the records that we sent out //b) new records from 'source' to be applied against this server if (priorResponse.getSyncImportRecords() == null) { log.debug("No records to process in response"); } else { // now process each incoming syncImportRecord, this is just status update for (SyncImportRecord importRecord : priorResponse.getSyncImportRecords()) { Context.getService(SyncIngestService.class).processSyncImportRecord(importRecord, origin); } } // now pull out the data that originated on the 'source' server and try to process it st = priorResponse.getSyncTransmission(); } // now process the syncTransmission if one was received if (st != null) { str = SyncUtilTransmission.processSyncTransmission(st, SyncUtil.getGlobalPropetyValueAsInteger(SyncConstants.PROPERTY_NAME_MAX_RECORDS_WEB)); } else log.info("st was null"); //send response this.sendResponse(str, isUpload, response); // never a situation where we want to actually use the model/view - either file download or http request return null; }
From source file:org.sakaiproject.jsf.renderer.InputFileUploadRenderer.java
/** * Return the FileItem (if present) for the given component. Subclasses * of this Renderer could get the FileItem in a different way. * First, try getting it from the request attributes (Sakai style). Then * try getting it from a method called getFileItem() on the HttpServletRequest * (unwrapping the request if necessary). *///from www. j av a 2s . c o m private static FileItem getFileItem(FacesContext context, UIComponent component) { String clientId = component.getClientId(context); HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest(); FileItem item = null; String fieldName = clientId + ID_INPUT_ELEMENT; // first try just getting it from the request attributes, // where the Sakai RequestFilter puts it. item = (FileItem) request.getAttribute(fieldName); if (item != null) return item; // For custom filter compatibility (MyFaces for example), // walk up the HttpServletRequestWrapper chain looking for a getFileItem() method. while (request != null) { // call the getFileItem() method by reflection, so as to not introduce a dependency // on MyFaces, and so the wrapper class that has getFileItem() doesn't have to // implement an interface (as long as it has the right method signature it'll work). try { Class reqClass = request.getClass(); Method getFileItemMethod = reqClass.getMethod("getFileItem", new Class[] { String.class }); Object returned = getFileItemMethod.invoke(request, new Object[] { fieldName }); if (returned instanceof FileItem) return (FileItem) returned; } catch (NoSuchMethodException nsme) { } catch (InvocationTargetException ite) { } catch (IllegalArgumentException iae) { } catch (IllegalAccessException iaxe) { } // trace up the request wrapper classes, looking for a getFileItem() method if (request instanceof HttpServletRequestWrapper) { request = (HttpServletRequest) ((HttpServletRequestWrapper) request).getRequest(); } else { request = null; } } return null; }
From source file:org.tangram.components.editor.EditingHandler.java
@LinkAction("/store/id_(.*)") public TargetDescriptor store(@LinkPart(1) String id, HttpServletRequest request, HttpServletResponse response) throws Exception { if (request.getAttribute(Constants.ATTRIBUTE_ADMIN_USER) == null) { throw new Exception("User may not edit"); } // if//from w w w .j a v a 2 s. co m Content bean = beanFactory.getBean(Content.class, id); JavaBean wrapper = new JavaBean(bean); Map<String, Object> newValues = new HashMap<>(); // List<String> deleteValues = new ArrayList<>(); RequestParameterAccess parameterAccess = viewUtilities.createParameterAccess(request); Map<String, String[]> parameterMap = parameterAccess.getParameterMap(); LOG.debug("store() # parameters {} for {}", parameterMap.size(), request.getClass().getName()); for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) { Entry<String, String[]> parameter = entry; String key = parameter.getKey(); if (!key.startsWith("cms.editor")) { try { String[] values = parameter.getValue(); if (LOG.isInfoEnabled()) { StringBuilder msg = new StringBuilder(128); msg.append("store() "); msg.append(key); msg.append(": "); for (String value : values) { msg.append(value); msg.append(' '); } // for LOG.info(msg.toString()); } // if Class<? extends Object> cls = wrapper.getType(key); String valueString = values.length == 1 ? values[0] : ""; Object value = propertyConverter.getStorableObject(bean, valueString, cls, request); LOG.info("store() value={}", value); if (!(Content.class.isAssignableFrom(cls) && value == null)) { newValues.put(key, value); } else { LOG.info("store() not setting value"); } // if if (Content.class.isAssignableFrom(cls) && "".equals(valueString)) { newValues.put(key, null); } // if } catch (Exception e) { throw new Exception("Cannot set value for " + key, e); } // try/catch } // if } // for for (String key : parameterAccess.getBlobNames()) { try { if (!key.startsWith("cms.editor")) { Class<? extends Object> cls = wrapper.getType(key); if (propertyConverter.isBlobType(cls)) { byte[] octets = parameterAccess.getData(key); newValues.put(key, propertyConverter.createBlob(octets)); } // if } // if } catch (Exception e) { throw new Exception("Cannot set value for " + key, e); } // try/catch } // for getMutableBeanFactory().beginTransaction(); wrapper = new JavaBean(bean); Exception e = null; for (Map.Entry<String, Object> property : newValues.entrySet()) { try { wrapper.set(property.getKey(), property.getValue()); } catch (Exception ex) { e = new Exception("Cannot set value for " + property.getKey(), ex); } // try/catch } // for if (!getMutableBeanFactory().persist(bean)) { throw new Exception("Could not persist bean " + bean.getId()); } // if LOG.debug("store() id={}", id); if (e != null) { throw e; } // if return describeTarget(bean); }