Example usage for org.w3c.dom Node getTextContent

List of usage examples for org.w3c.dom Node getTextContent

Introduction

In this page you can find the example usage for org.w3c.dom Node getTextContent.

Prototype

public String getTextContent() throws DOMException;

Source Link

Document

This attribute returns the text content of this node and its descendants.

Usage

From source file:com.amalto.core.util.Util.java

/**
 * Executes a BeforeDeleting process if any
 * //from   w  w  w . ja v  a  2 s.c o  m
 * @param clusterName A data cluster name
 * @param concept A concept/type name
 * @param ids Id of the document being deleted
 * @throws Exception If something went wrong
 */
@SuppressWarnings("unchecked")
public static BeforeDeleteResult beforeDeleting(String clusterName, String concept, String[] ids,
        String operationType) throws Exception {
    // check before deleting transformer
    boolean isBeforeDeletingTransformerExist = false;
    Collection<TransformerV2POJOPK> transformers = getTransformerV2CtrlLocal().getTransformerPKs("*");
    for (TransformerV2POJOPK id : transformers) {
        if (id.getIds()[0].equals("beforeDeleting_" + concept)) {
            isBeforeDeletingTransformerExist = true;
            break;
        }
    }
    if (isBeforeDeletingTransformerExist) {
        try {
            // call before deleting transformer
            // load the item
            ItemPOJOPK itemPk = new ItemPOJOPK(new DataClusterPOJOPK(clusterName), concept, ids);
            ItemPOJO pojo = ItemPOJO.load(itemPk);
            String xml = null;
            if (pojo == null) {// load from recycle bin
                DroppedItemPOJOPK droppedItemPk = new DroppedItemPOJOPK(itemPk, "/");//$NON-NLS-1$
                DroppedItemPOJO droppedItem = Util.getDroppedItemCtrlLocal().loadDroppedItem(droppedItemPk);
                if (droppedItem != null) {
                    xml = droppedItem.getProjection();
                    Document doc = Util.parse(xml);
                    Node item = (Node) XPathFactory.newInstance().newXPath().evaluate("//ii/p", doc, //$NON-NLS-1$
                            XPathConstants.NODE);
                    if (item != null && item instanceof Element) {
                        NodeList list = item.getChildNodes();
                        Node node = null;
                        for (int i = 0; i < list.getLength(); i++) {
                            if (list.item(i) instanceof Element) {
                                node = list.item(i);
                                break;
                            }
                        }
                        if (node != null) {
                            xml = Util.nodeToString(node);
                        }
                    }
                }
            } else {
                xml = pojo.getProjectionAsString();
            }
            // Create before deleting update report
            String username;
            try {
                username = LocalUser.getLocalUser().getUsername();
            } catch (Exception e1) {
                LOGGER.error(e1);
                throw e1;
            }
            String key = "";
            if (ids != null) {
                for (int i = 0; i < ids.length; i++) {
                    key += ids[i];
                    if (i != ids.length - 1) {
                        key += ".";
                    }
                }
            }
            String resultUpdateReport = "" + "<Update>" + "<UserName>" + username + "</UserName>" + "<Source>"
                    + UpdateReportPOJO.GENERIC_UI_SOURCE + "</Source>" + "<TimeInMillis>"
                    + System.currentTimeMillis() + "</TimeInMillis>" + "<OperationType>"
                    + StringEscapeUtils.escapeXml(operationType) + "</OperationType>" + "<DataCluster>"
                    + clusterName + "</DataCluster>" + "<DataModel>" + StringUtils.EMPTY + "</DataModel>"
                    + "<Concept>" + StringEscapeUtils.escapeXml(concept) + "</Concept>" + "<Key>"
                    + StringEscapeUtils.escapeXml(key) + "</Key>";
            resultUpdateReport += "</Update>";
            // Proceed with execution
            String exchangeData = mergeExchangeData(xml, resultUpdateReport);
            final String runningKey = "XtentisWSBean.executeTransformerV2.beforeDeleting.running";
            TransformerContext context = new TransformerContext(
                    new TransformerV2POJOPK("beforeDeleting_" + concept));
            context.put(runningKey, Boolean.TRUE);
            com.amalto.core.server.api.Transformer ctrl = getTransformerV2CtrlLocal();
            TypedContent wsTypedContent = new TypedContent(exchangeData.getBytes("UTF-8"),
                    "text/xml; charset=utf-8");
            ctrl.execute(context, wsTypedContent, new TransformerCallBack() {

                @Override
                public void contentIsReady(TransformerContext context) throws XtentisException {
                    if (LOGGER.isDebugEnabled()) {
                        LOGGER.debug("XtentisWSBean.executeTransformerV2.beforeDeleting.contentIsReady() ");
                    }
                }

                @Override
                public void done(TransformerContext context) throws XtentisException {
                    if (LOGGER.isDebugEnabled()) {
                        LOGGER.debug("XtentisWSBean.executeTransformerV2.beforeDeleting.done() ");
                    }
                    context.put(runningKey, Boolean.FALSE);
                }
            });
            while ((Boolean) context.get(runningKey)) { // TODO Poor-man synchronization here
                Thread.sleep(100);
            }
            // TODO process no plug-in issue
            String outputErrorMessage = null;
            // Scan the entries - in priority, aka the content of the 'output_error_message' entry.
            for (Entry<String, TypedContent> entry : context.getPipelineClone().entrySet()) {
                if (ITransformerConstants.VARIABLE_OUTPUT_OF_BEFORESAVINGTRANFORMER.equals(entry.getKey())) {
                    outputErrorMessage = new String(entry.getValue().getContentBytes(), "UTF-8");
                    break;
                }
            }
            // handle error message
            BeforeDeleteResult result = new BeforeDeleteResult();
            if (outputErrorMessage == null) {
                LOGGER.warn("No message generated by before delete process.");
                result.type = "info"; //$NON-NLS-1$
                result.message = StringUtils.EMPTY;
            } else {
                if (outputErrorMessage.length() > 0) {
                    Document doc = Util.parse(outputErrorMessage);
                    // TODO what if multiple error nodes ?
                    String xpath = "//report/message"; //$NON-NLS-1$
                    Node errorNode = (Node) XPathFactory.newInstance().newXPath().evaluate(xpath, doc,
                            XPathConstants.NODE);
                    if (errorNode instanceof Element) {
                        Element errorElement = (Element) errorNode;
                        result.type = errorElement.getAttribute("type"); //$NON-NLS-1$
                        Node child = errorElement.getFirstChild();
                        if (child instanceof Text) {
                            result.message = child.getTextContent();
                        }
                    }
                } else {
                    result.type = "error"; //$NON-NLS-1$
                    result.message = "<report><message type=\"error\"/></report>"; //$NON-NLS-1$
                }
            }
            return result;
        } catch (Exception e) {
            LOGGER.error(e);
            throw e;
        }
    }
    return null;
}

From source file:de.ingrid.iplug.opensearch.converter.IngridRSSConverter.java

/**
 * Calculate a document id so that it can be identified later when looking
 * for the detail./*w w  w.java  2  s. c om*/
 * 
 * @param item
 * @return
 * @throws XPathExpressionException
 */
private String getDocumentId(Node item) throws XPathExpressionException {
    XPath xpath = XPathFactory.newInstance().newXPath();
    Node node = (Node) xpath.evaluate("docid", item, XPathConstants.NODE);
    if (node == null) {
        return String.valueOf(customDocId++);
    } else {
        return node.getTextContent();
    }
}

From source file:se.vgregion.incidentreport.pivotaltracker.impl.PivotalTrackerServiceImpl.java

protected List<TyckTillProjectData> getProjectData(InputStream xml) throws Exception {
    List<TyckTillProjectData> result = new ArrayList<TyckTillProjectData>();
    DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
    docBuilderFactory.setValidating(false);
    docBuilderFactory.setNamespaceAware(false);
    DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
    Document doc = docBuilder.parse(xml);
    xml.close();//from www  . jav  a 2  s . co m

    NodeList projectNodes = doc.getElementsByTagName("project");
    // System.out.println("antal projekt=" + projectNodes.getLength());
    for (int s = 0; s < projectNodes.getLength(); s++) {
        Node projectNode = projectNodes.item(s);
        NodeList projectChildNodes = projectNode.getChildNodes();
        TyckTillProjectData data = new TyckTillProjectData();
        for (int i = 0; i < projectChildNodes.getLength(); i++) {
            Node projectAttributeNode = projectChildNodes.item(i);
            String nodeName = projectAttributeNode.getNodeName();
            String nodeValue = projectAttributeNode.getTextContent();
            short nodeType = projectAttributeNode.getNodeType();

            if (nodeType == 1) {
                // System.out.println("node:" + nodeName + "=" + nodeValue);
                if ("id".equals(nodeName)) {
                    data.setId(nodeValue);
                } else if ("name".equals(nodeName)) {
                    data.setName(nodeValue);
                } else if ("memberships".equals(nodeName)) {
                    NodeList mNodes = projectAttributeNode.getChildNodes();

                    for (int k = 0; k < mNodes.getLength(); k++) {
                        Node mNode = mNodes.item(k);// membership
                        NodeList mNodes2 = mNode.getChildNodes();
                        for (int m = 0; m < mNodes2.getLength(); m++) {
                            Node maNode = mNodes2.item(m);// membership
                            if (maNode.getNodeType() == 1) {
                                if ("person".equals(maNode.getNodeName())) {
                                    data.addMember(maNode.getTextContent());
                                } else {
                                    // System.out.println(" fgfgf=" +
                                    // maNode.getNodeName());
                                }
                            }
                        }

                    }

                }
            }
        }
        result.add(data);

    }

    return result;
}

From source file:com.evolveum.midpoint.util.DOMUtil.java

/**
 * Remove comments and whitespace-only text nodes
 *///from  w  w  w .ja  v a  2  s  .c o  m
private static List<Node> canonizeNodeList(NodeList nodelist) {
    List<Node> list = new ArrayList<Node>(nodelist.getLength());
    for (int i = 0; i < nodelist.getLength(); i++) {
        Node aItem = nodelist.item(i);
        if (aItem.getNodeType() == Node.COMMENT_NODE) {
            continue;
        } else if (aItem.getNodeType() == Node.TEXT_NODE) {
            if (aItem.getTextContent().matches("\\s*")) {
                continue;
            }
        }
        list.add(aItem);
    }
    return list;
}

From source file:edu.lternet.pasta.portal.search.MapResultSetUtility.java

/**
 * Using search results XML as input, compose a JavaScript array that contains
 * the data necessary to render the search results in a Google Maps script
 * that uses the Marker Clusterer component.
 * //  ww  w  . ja  v a2  s. c o  m
 * @param    xml  search resuts XML string
 * @return   a string representation of the JavaScript array
 */
public String parseResultSet(String xml) {
    String jsArray = "";
    StringBuilder jsArrayBuilder = new StringBuilder("[\n");

    if (xml != null) {
        InputStream inputStream = null;
        try {
            inputStream = IOUtils.toInputStream(xml, "UTF-8");
            DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            CachedXPathAPI xpathapi = new CachedXPathAPI();

            Document document = null;
            document = documentBuilder.parse(inputStream);

            if (document != null) {
                Node numFoundNode = null;
                numFoundNode = xpathapi.selectSingleNode(document, "//resultset/@numFound");
                if (numFoundNode != null) {
                    String numFoundStr = numFoundNode.getNodeValue();
                    this.numFound = new Integer(numFoundStr);
                }

                NodeList dataPackageNodeList = xpathapi.selectNodeList(document, "//resultset/document");

                if (dataPackageNodeList != null) {
                    Set<String> coordinatesSet = new TreeSet<String>();
                    for (int i = 0; i < dataPackageNodeList.getLength(); i++) {
                        Node dataPackageNode = dataPackageNodeList.item(i);

                        String packageIdField = null;
                        String titleField = null;
                        String titleLinkField = null;
                        String pubDateField = null;
                        String locationField = null;

                        NodeList coordinatesNodeList = xpathapi.selectNodeList(dataPackageNode,
                                COORDINATES_PATH);

                        /*
                         * If we can't determine the coordinates, we can't map the
                         * data package, so just continue to the next data package
                         */
                        if (coordinatesNodeList != null) {
                            if (coordinatesNodeList.getLength() > 0) {
                                for (int j = 0; j < coordinatesNodeList.getLength(); j++) {
                                    if (j == 1)
                                        break;
                                    Node coordinatesNode = coordinatesNodeList.item(j);
                                    String coordinates = coordinatesNode.getTextContent();
                                    boolean useOffset = false;
                                    locationField = composeLocationField(coordinates, coordinatesSet,
                                            useOffset);
                                    if (locationField == null) {
                                        continue;
                                    } else {
                                        coordinatesSet.add(locationField);
                                    }
                                }
                            } else {
                                continue;
                            }
                        } else {
                            continue;
                        }

                        String packageId = null;
                        Node packageIdNode = xpathapi.selectSingleNode(dataPackageNode, PACKAGEID_PATH);
                        if (packageIdNode != null) {
                            packageId = packageIdNode.getTextContent();
                            packageIdField = composePackageIdField(packageId);
                        }

                        Node titleNode = xpathapi.selectSingleNode(dataPackageNode, TITLE_PATH);
                        if (titleNode != null) {
                            String title = titleNode.getTextContent();
                            titleField = composeTitleField(title);
                            if (packageId != null) {
                                titleLinkField = composeTitleLinkField(title, packageId);
                            }
                        }

                        Node pubDateNode = xpathapi.selectSingleNode(dataPackageNode, PUBDATE_PATH);
                        if (pubDateNode != null) {
                            String pubDate = pubDateNode.getTextContent();
                            pubDateField = composePubDateField(pubDate);
                        }

                        String jsArrayElement = composeArrayElement(packageIdField, titleField, titleLinkField,
                                pubDateField, locationField);
                        jsArrayBuilder.append(jsArrayElement);
                    }
                }
            }
        } catch (Exception e) {
            logger.error("Error parsing search result set: " + e.getMessage());
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    ;
                }
            }
        }
    }

    jsArrayBuilder.append("];\n");
    jsArray = jsArrayBuilder.toString();

    return jsArray;
}

From source file:org.openmrs.module.sync.web.controller.HistoryListController.java

@SuppressWarnings("unchecked")
@RequestMapping(value = Views.HISTORY, method = RequestMethod.GET)
public void showThePage(ModelMap modelMap,
        @RequestParam(value = "firstRecordId", required = false) Integer firstRecordId,
        @RequestParam(value = "size", required = false) Integer size,
        @RequestParam(value = "state", required = false) String state) throws Exception {

    SyncRecord latestRecord = null;/*from ww w .  java  2 s  . c  o  m*/
    SyncRecord earliestRecord = null;
    // default the list size to 20 items
    if (size == null) {
        AdministrationService as = Context.getAdministrationService();
        String max = as.getGlobalProperty(SyncConstants.PROPERTY_NAME_MAX_PAGE_RECORDS,
                SyncConstants.PROPERTY_NAME_MAX_RETRY_COUNT_DEFAULT);
        size = Integer.valueOf(max);
    }

    log.debug("Vewing history page with size: " + size);

    List<SyncRecord> recordList = null;

    // only fill the record list if the user has authenticated properly
    if (Context.isAuthenticated()) {
        SyncService ss = Context.getService(SyncService.class);
        if (!StringUtils.hasText(state))
            recordList = ss.getSyncRecords(firstRecordId, size);
        else {
            SyncRecordState[] states = new SyncRecordState[] { SyncRecordState.valueOf(state) };
            recordList = ss.getSyncRecords(states, size, firstRecordId);
        }
        latestRecord = ss.getLatestRecord();
        earliestRecord = ss.getEarliestRecord(null);

    }

    if (recordList == null)
        recordList = Collections.emptyList();

    Map<String, String> recordTypes = new HashMap<String, String>();
    Map<Object, String> itemTypes = new HashMap<Object, String>();
    Map<Object, String> itemUuids = new HashMap<Object, String>();
    Map<String, String> recordText = new HashMap<String, String>();
    Map<String, String> recordChangeType = new HashMap<String, String>();

    // for paging to work, set the firstRecordId as the current first item in the list
    if (recordList.size() > 0) {
        firstRecordId = recordList.get(0).getRecordId();
    }

    for (SyncRecord record : recordList) {

        String mainClassName = null;
        String mainUuid = null;
        String mainState = null;

        for (SyncItem item : record.getItems()) {
            String syncItem = item.getContent();
            mainState = item.getState().toString();
            Record xml = Record.create(syncItem);
            Item root = xml.getRootItem();
            String className = root.getNode().getNodeName().substring("org.openmrs.".length());
            itemTypes.put(item.getKey().getKeyValue(), className);
            if (mainClassName == null)
                mainClassName = className;

            // now we have to go through the item child nodes to find the real UUID that we want
            NodeList nodes = root.getNode().getChildNodes();
            for (int i = 0; i < nodes.getLength(); i++) {
                Node n = nodes.item(i);
                String propName = n.getNodeName();
                if (propName.equalsIgnoreCase("uuid")) {
                    String uuid = n.getTextContent();
                    itemUuids.put(item.getKey().getKeyValue(), uuid);
                    if (mainUuid == null)
                        mainUuid = uuid;
                }
            }
        }

        // persistent sets should show something other than their mainClassName (persistedSet)
        if (mainClassName.indexOf("Persistent") >= 0)
            mainClassName = record.getContainedClasses();

        recordTypes.put(record.getUuid(), mainClassName);
        recordChangeType.put(record.getUuid(), mainState);

        // refactored - CA 21 Jan 2008
        String displayName = "";
        try {
            displayName = SyncUtil.displayName(mainClassName, mainUuid);
        } catch (Exception e) {
            // some methods like Concept.getName() throw Exception s all the time...
            displayName = "";
        }
        if (displayName != null)
            if (displayName.length() > 0)
                recordText.put(record.getUuid(), displayName);
    }

    modelMap.put("syncRecords", recordList);

    modelMap.put("recordTypes", recordTypes);
    modelMap.put("itemTypes", itemTypes);
    modelMap.put("itemUuids", itemUuids);
    modelMap.put("recordText", recordText);
    modelMap.put("recordChangeType", recordChangeType);

    modelMap.put("parent", Context.getService(SyncService.class).getParentServer());
    modelMap.put("servers", Context.getService(SyncService.class).getRemoteServers());
    modelMap.put("syncDateDisplayFormat", TimestampNormalizer.DATETIME_DISPLAY_FORMAT);

    modelMap.put("firstRecordId", firstRecordId);

    if (latestRecord != null)
        modelMap.put("latestRecordId", latestRecord.getRecordId());

    if (earliestRecord != null) {
        if (earliestRecord.getRecordId() == recordList.get(recordList.size() - 1).getRecordId())
            modelMap.put("isEarliestRecord", "true");
    }
    modelMap.put("size", size);
}

From source file:com.amalto.core.save.context.CreateActions.java

private boolean doCreate(FieldMetadata simpleField) {
    // Under some circumstances, do not generate action(s) for UUID/AUTOINCREMENT (see TMDM-4473)
    boolean doCreate = true;
    if (!path.isEmpty()) {
        // Only apply the do-create-check for UUID/AUTO_INCREMENT field to improve the performance
        String typeName = simpleField.getType().getName();
        if (EUUIDCustomType.AUTO_INCREMENT.getName().equalsIgnoreCase(typeName)
                || EUUIDCustomType.UUID.getName().equalsIgnoreCase(typeName)) {
            FieldMetadata parentField = path.peek().fieldMetadata;
            if (parentField != null) {
                boolean isParentOptional = !parentField.isMandatory();
                boolean isEmpty = false;
                Accessor accessor = document.createAccessor(getRealPath());
                Node parentNode = null;
                if (accessor instanceof DOMAccessor) {
                    parentNode = ((DOMAccessor) accessor).getNode();
                }/*from ww w.  ja va2 s. c  o m*/
                if (parentNode == null) {
                    isEmpty = true;
                } else if (parentNode.getTextContent() == null || parentNode.getTextContent().isEmpty()) {
                    isEmpty = true;
                }
                if (isParentOptional && isEmpty) {
                    doCreate = false;
                }
            }
        }
    }
    return doCreate;
}

From source file:de.ingrid.iplug.opensearch.converter.IngridRSSConverter.java

/**
 * Set an IngridHitDetail with data that is needed by default.
 * //ww w  .  j  a v a2  s.  c o m
 * @param hit
 * @param item
 * @param groupedBy
 * @throws XPathExpressionException
 */
private void setIngridHitDetail(IngridHit hit, Node item, String groupedBy) throws XPathExpressionException {
    XPath xpath = XPathFactory.newInstance().newXPath();

    // get plug id
    Node node = (Node) xpath.evaluate("plugid", item, XPathConstants.NODE);
    if (node != null) {
        hit.setPlugId(node.getTextContent());
    }

    // get doc id
    hit.setDocumentId(getDocumentId(item));

    // =====================================================================
    // the following must be put into the HitDetail
    // this detail will be put into a cache and returned when getDetail()
    // is called
    // =====================================================================
    IngridHitDetail hitDetail = new IngridHitDetail(hit, (String) hit.get("title"),
            (String) hit.get("abstract"));
    node = (Node) xpath.evaluate("timeReference/start", item, XPathConstants.NODE);
    if (node != null) {
        hitDetail.put("t1", node.getTextContent());
    }
    node = (Node) xpath.evaluate("timeReference/stop", item, XPathConstants.NODE);
    if (node != null) {
        hitDetail.put("t2", node.getTextContent());
    }

    // set partner and provider
    setPartnerAndProvider(hitDetail, item);

    // get box
    node = (Node) xpath.evaluate("box", item, XPathConstants.NODE);
    if (node != null) {
        String[] box = node.getTextContent().split(" ");
        hitDetail.put("x1", box[0]);
        hitDetail.put("y1", box[0]);
        hitDetail.put("x2", box[0]);
        hitDetail.put("y2", box[0]);
    }

    // add grouping information
    if (groupedBy != null) {
        String groupInfos = null;

        if (IngridQuery.GROUPED_BY_PARTNER.equalsIgnoreCase(groupedBy)) {
            String[] partner = (String[]) hitDetail.get("partner");
            if (partner != null && partner.length > 0)
                groupInfos = partner[0];
        } else if (IngridQuery.GROUPED_BY_ORGANISATION.equalsIgnoreCase(groupedBy)) {
            String[] provider = (String[]) hitDetail.get("provider");
            if (provider != null && provider.length > 0)
                groupInfos = provider[0];
        } else if (IngridQuery.GROUPED_BY_DATASOURCE.equalsIgnoreCase(groupedBy)) {
            groupInfos = (String) hit.get("url");
            try {
                groupInfos = new URL(groupInfos).getHost();
            } catch (MalformedURLException e) {
                log.warn("can not group url: " + groupInfos, e);
            }
        }
        if (groupInfos != null) {
            hit.addGroupedField(groupInfos);
        }
    }

    // add some important default values
    hitDetail.setDocumentId(hit.getDocumentId());
    hitDetail.setPlugId(hit.getPlugId());
    hitDetail.setDataSourceId(hit.getDataSourceId());
    hitDetail.put("url", hit.get("url"));

    // put detail into cache
    cache.put(new Element(hit.getDocumentId(), hitDetail));
}

From source file:org.openmrs.module.sync.SyncUtil.java

public static String getAttribute(NodeList nodes, String attName, ArrayList<Field> allFields) {
    String ret = null;// w w  w .  ja v a  2s .  co  m
    if (nodes != null && attName != null) {
        for (int i = 0; i < nodes.getLength(); i++) {
            Node n = nodes.item(i);
            String propName = n.getNodeName();
            if (attName.equals(propName)) {
                Object obj = SyncUtil.valForField(propName, n.getTextContent(), allFields, n);
                if (obj != null)
                    ret = obj.toString();
            }
        }
    }

    return ret;
}

From source file:edu.ur.ir.ir_import.service.DefaultCollectionImportService.java

/**
 * Get a link from a individual link node
 * @param linkNode - xml containing link information
 * @return - created link/*  w w  w. j  a  v  a 2 s. c  o m*/
 */
private void addLink(Node linkNode, InstitutionalCollection c) {
    NodeList children = linkNode.getChildNodes();
    String name = null;
    String url = null;
    for (int index = 0; index < children.getLength(); index++) {
        Node child = children.item(index);
        if (child.getNodeName().equals("name")) {
            name = child.getTextContent();
        } else if (child.getNodeName().equals("url")) {
            url = child.getTextContent();
        }
    }
    try {
        c.addLink(name, url);
    } catch (DuplicateNameException e) {
        log.error(e);
    }
}