Java Code Examples for org.elasticsearch.common.xcontent.XContentParser#close()

The following examples show how to use org.elasticsearch.common.xcontent.XContentParser#close() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: SQLXContentSourceParser.java    From Elasticsearch with Apache License 2.0 6 votes vote down vote up
public void parseSource(BytesReference source) throws SQLParseException {
    XContentParser parser = null;
    try {
        if (source != null && source.length() != 0) {
            parser = XContentFactory.xContent(source).createParser(source);
            parse(parser);
        }
        validate();
    } catch (Exception e) {
        String sSource = "_na_";
        try {
            sSource = XContentHelper.convertToJson(source, false);
        } catch (Throwable e1) {
            // ignore
        }
        throw new SQLParseException("Failed to parse source [" + sSource + "]", e);
    } finally {
        if (parser != null) {
            parser.close();
        }
    }
}
 
Example 2
Source File: PercolatorService.java    From Elasticsearch with Apache License 2.0 6 votes vote down vote up
private ParsedDocument parseFetchedDoc(PercolateContext context, BytesReference fetchedDoc, IndexService documentIndexService, String index, String type) {
    ParsedDocument doc = null;
    XContentParser parser = null;
    try {
        parser = XContentFactory.xContent(fetchedDoc).createParser(fetchedDoc);
        MapperService mapperService = documentIndexService.mapperService();
        DocumentMapperForType docMapper = mapperService.documentMapperWithAutoCreate(type);
        doc = docMapper.getDocumentMapper().parse(source(parser).index(index).type(type).flyweight(true));

        if (context.highlight() != null) {
            doc.setSource(fetchedDoc);
        }
    } catch (Throwable e) {
        throw new ElasticsearchParseException("failed to parse request", e);
    } finally {
        if (parser != null) {
            parser.close();
        }
    }

    if (doc == null) {
        throw new ElasticsearchParseException("No doc to percolate in the request");
    }

    return doc;
}
 
Example 3
Source File: SQLRequestParser.java    From crate with Apache License 2.0 6 votes vote down vote up
public static SQLRequestParseContext parseSource(BytesReference source) throws IOException {
    if (source.length() == 0) {
        throw new SQLParseException("Missing request body");
    }
    XContentParser parser = null;
    try {
        SQLRequestParseContext parseContext = new SQLRequestParseContext();
        parser = XContentFactory.xContent(XContentType.JSON).createParser(
            NamedXContentRegistry.EMPTY, DeprecationHandler.THROW_UNSUPPORTED_OPERATION, BytesReference.toBytes(source));
        parse(parseContext, parser);
        validate(parseContext);
        return parseContext;
    } catch (Exception e) {
        String sSource = "_na_";
        try {
            sSource = XContentHelper.convertToJson(source, XContentType.JSON);
        } catch (Throwable e1) {
            // ignore
        }
        throw new SQLParseException("Failed to parse source [" + sSource + "]", e);
    } finally {
        if (parser != null) {
            parser.close();
        }
    }
}
 
Example 4
Source File: ContentBuilderUtil.java    From mt-flume with Apache License 2.0 6 votes vote down vote up
public static void addComplexField(XContentBuilder builder, String fieldName,
    XContentType contentType, byte[] data) throws IOException {
  XContentParser parser = null;
  try {
    XContentBuilder tmp = jsonBuilder();
    parser = XContentFactory.xContent(contentType).createParser(data);
    parser.nextToken();
    tmp.copyCurrentStructure(parser);
    builder.field(fieldName, tmp);
  } catch (JsonParseException ex) {
    // If we get an exception here the most likely cause is nested JSON that
    // can't be figured out in the body. At this point just push it through
    // as is, we have already added the field so don't do it again
    addSimpleField(builder, fieldName, data);
  } finally {
    if (parser != null) {
      parser.close();
    }
  }
}
 
Example 5
Source File: XmlBuilderTest.java    From elasticsearch-xml with Apache License 2.0 6 votes vote down vote up
public static String convertToXml(XmlXParams params, byte[] data, int offset, int length, boolean prettyPrint) throws IOException {
    XmlXContentType xmlXContentType = XmlXContentFactory.xContentType(data, offset, length);
    XContentParser parser = null;
    try {
        parser = XmlXContentFactory.xContent(xmlXContentType).createParser(data, offset, length);
        parser.nextToken();
        XmlXContentBuilder builder = XmlXContentFactory.xmlBuilder(params);
        if (prettyPrint) {
            builder.prettyPrint();
        }
        builder.copyCurrentStructure(parser);
        return builder.string();
    } finally {
        if (parser != null) {
            parser.close();
        }
    }
}
 
Example 6
Source File: XmlFilter.java    From elasticsearch-xml with Apache License 2.0 6 votes vote down vote up
@Override
public BytesReference content() {
    if (isXml(request)) {
        XContentParser parser = null;
        try {
            BytesReference b = request.content();
            parser = XmlXContentFactory.xContent(XmlXContentType.XML).createParser(b);
            parser.nextToken();
            XContentBuilder builder = XContentFactory.jsonBuilder();
            builder.copyCurrentStructure(parser);
            return builder.bytes();
        } catch (Throwable e) {
            logger.error(e.getMessage(), e);
        } finally {
            if (parser != null) {
                parser.close();
            }
        }
    }
    return request.content();
}
 
Example 7
Source File: ContentBuilderUtil.java    From ElasticsearchSink2 with Apache License 2.0 5 votes vote down vote up
public static void addComplexField(XContentBuilder builder, String fieldName,
    XContentType contentType, byte[] data) throws IOException {
  XContentParser parser = null;
  try {
    // Elasticsearch will accept JSON directly but we need to validate that
    // the incoming event is JSON first. Sadly, the elasticsearch JSON parser
    // is a stream parser so we need to instantiate it, parse the event to
    // validate it, then instantiate it again to provide the JSON to
    // elasticsearch.
    // If validation fails then the incoming event is submitted to
    // elasticsearch as plain text.
    parser = XContentFactory.xContent(contentType).createParser(data);
    while (parser.nextToken() != null) {};

    // If the JSON is valid then include it
    parser = XContentFactory.xContent(contentType).createParser(data);
    // Add the field name, but not the value.
    builder.field(fieldName);
    // This will add the whole parsed content as the value of the field.
    builder.copyCurrentStructure(parser);
  } catch (JsonParseException ex) {
    // If we get an exception here the most likely cause is nested JSON that
    // can't be figured out in the body. At this point just push it through
    // as is
    addSimpleField(builder, fieldName, data);
  } finally {
    if (parser != null) {
      parser.close();
    }
  }
}
 
Example 8
Source File: AccountRestAction.java    From elasticsearch-auth with Apache License 2.0 5 votes vote down vote up
@Override
protected void handleRequest(final RestRequest request,
        final RestChannel channel, final Client client) {
    final BytesReference content = request.content();
    final XContentType xContentType = XContentFactory.xContentType(content);
    XContentParser parser = null;
    String authenticator = null;
    String username = null;
    String password = null;
    String[] roles = null;
    try {
        parser = XContentFactory.xContent(xContentType).createParser(
                content);
        final XContentParser.Token t = parser.nextToken();
        if (t != null) {
            final Map<String, Object> contentMap = parser.map();
            authenticator = MapUtil.getAsString(contentMap,
                    "authenticator", null);
            username = MapUtil.getAsString(contentMap, "username", null);
            password = MapUtil.getAsString(contentMap, "password", null);
            roles = MapUtil.getAsArray(contentMap, "roles", new String[0]);
        }
    } catch (final Exception e) {
        logger.error("Could not parse the content.", e);
        ResponseUtil.send(request, channel, RestStatus.BAD_REQUEST,
                "message", "Could not parse the content.");
        return;
    } finally {
        if (parser != null) {
            parser.close();
        }
    }

    processRequest(request, channel, authenticator, username, password,
            roles);

}
 
Example 9
Source File: IndexAuthenticator.java    From elasticsearch-auth with Apache License 2.0 5 votes vote down vote up
@Override
public void login(final RestRequest request,
        final ActionListener<String[]> listener) {
    String username = request.param(usernameKey);
    String password = request.param(passwordKey);
    final BytesReference content = request.content();
    final XContentType xContentType = XContentFactory.xContentType(content);
    XContentParser parser = null;
    try {
        parser = XContentFactory.xContent(xContentType).createParser(
                content);
        final XContentParser.Token t = parser.nextToken();
        if (t != null) {
            final Map<String, Object> contentMap = parser.map();
            username = MapUtil.getAsString(contentMap, usernameKey,
                    username);
            password = MapUtil.getAsString(contentMap, passwordKey,
                    password);
        }
    } catch (final Exception e) {
        listener.onFailure(e);
        return;
    } finally {
        if (parser != null) {
            parser.close();
        }
    }

    if (username == null) {
        listener.onResponse(new String[0]);
        return;
    }

    processLogin(username, password, listener);

}
 
Example 10
Source File: XmlFilter.java    From elasticsearch-xml with Apache License 2.0 5 votes vote down vote up
@Override
public void sendResponse(RestResponse response) {
    if (!response.status().equals(RestStatus.OK)) {
        channel.sendResponse(response);
    }
    if (isXml(request)) {
        XContentParser parser = null;
        try {
            String string = response.content().toUtf8(); // takes some space ... :(
            XContentType xContentType = XContentFactory.xContentType(string);
            parser = XContentFactory.xContent(xContentType).createParser(string);
            parser.nextToken();
            XmlXContentBuilder builder = XmlXContentFactory.xmlBuilder(params);
            if (request.paramAsBoolean("pretty", false)) {
                builder.prettyPrint();
            }
            builder.copyCurrentStructure(parser);
            BytesRestResponse restResponse = new BytesRestResponse(RestStatus.OK, "text/xml; charset=UTF-8", builder.bytes());
            channel.sendResponse(restResponse);
            return;
        } catch (Throwable e) {
            logger.error(e.getMessage(), e);
            channel.sendResponse(new BytesRestResponse(RestStatus.INTERNAL_SERVER_ERROR, e.getMessage()));
            return;
        } finally {
            if (parser != null) {
                parser.close();
            }
        }
    }
    channel.sendResponse(response);
}
 
Example 11
Source File: RestHandlerUtilsTests.java    From anomaly-detection with Apache License 2.0 5 votes vote down vote up
public void testCreateXContentParser() throws IOException {
    RestRequest request = new FakeRestRequest();
    RestChannel channel = new FakeRestChannel(request, false, 1);
    XContentBuilder builder = builder().startObject().field("test", "value").endObject();
    BytesReference bytesReference = BytesReference.bytes(builder);
    XContentParser parser = RestHandlerUtils.createXContentParser(channel, bytesReference);
    parser.close();
}
 
Example 12
Source File: ElasticsearchIntegrationTest.java    From openshift-elasticsearch-plugin with Apache License 2.0 5 votes vote down vote up
protected static BytesReference readXContent(final Reader reader, final XContentType contentType) throws IOException {
    XContentParser parser = null;
    try {
        parser = XContentFactory.xContent(contentType).createParser(NamedXContentRegistry.EMPTY, reader);
        parser.nextToken();
        final XContentBuilder builder = XContentFactory.jsonBuilder();
        builder.copyCurrentStructure(parser);
        return builder.bytes();
    } finally {
        if (parser != null) {
            parser.close();
        }
    }
}
 
Example 13
Source File: ConfigurationLoader.java    From openshift-elasticsearch-plugin with Apache License 2.0 5 votes vote down vote up
private Settings toSettings(final BytesReference ref, final String type) {
    if (ref == null || ref.length() == 0) {
        return null;
    }
    
    XContentParser parser = null;

    try {
        parser = XContentHelper.createParser(NamedXContentRegistry.EMPTY, ref, XContentType.JSON);
        parser.nextToken();
        parser.nextToken();
     
        if(!type.equals((parser.currentName()))) {
            return null;
        }
        
        parser.nextToken();
        
        return Settings.builder().put(new JsonSettingsLoader(true).load(parser.binaryValue())).build();
    } catch (final IOException e) {
        throw ExceptionsHelper.convertToElastic(e);
    } finally {
        if(parser != null) {
            parser.close();
        }
    }
}
 
Example 14
Source File: ElasticsearchResource.java    From newsleak with GNU Affero General Public License v3.0 5 votes vote down vote up
/**
 * Creates a new elasticsearch index and adds a mapping for the document type.
 * Previously existing indexes will be removed.
 *
 * @throws Exception
 *             the exception
 */
private void createIndex() throws Exception {

	boolean exists = client.admin().indices().prepareExists(mIndex).execute().actionGet().isExists();

	// remove preexisting index
	if (exists) {
		logger.log(Level.INFO, "Preexisting index " + mIndex + " will be removed.");
		DeleteIndexResponse deleteResponse = client.admin().indices().delete(new DeleteIndexRequest(mIndex))
				.actionGet();
		if (deleteResponse.isAcknowledged()) {
			logger.log(Level.INFO, "Preexisting index " + mIndex + " successfully removed.");
			exists = false;
		}
	}

	// create schema mapping from file
	logger.log(Level.INFO, "Index " + mIndex + " will be created.");
	String docMapping = new String(Files.readAllBytes(Paths.get(documentMappingFile)));

	XContentBuilder builder = XContentFactory.jsonBuilder();
	XContentParser parser = XContentFactory.xContent(XContentType.JSON).createParser(docMapping.getBytes());
	parser.close();
	builder.copyCurrentStructure(parser);

	CreateIndexRequestBuilder createIndexRequestBuilder = client.admin().indices().prepareCreate(mIndex);
	createIndexRequestBuilder.addMapping(DOCUMENT_TYPE, builder);
	createIndexRequestBuilder.execute().actionGet();

}
 
Example 15
Source File: TransportSuggestAction.java    From Elasticsearch with Apache License 2.0 5 votes vote down vote up
@Override
protected ShardSuggestResponse shardOperation(ShardSuggestRequest request) {
    IndexService indexService = indicesService.indexServiceSafe(request.shardId().getIndex());
    IndexShard indexShard = indexService.shardSafe(request.shardId().id());
    ShardSuggestMetric suggestMetric = indexShard.getSuggestMetric();
    suggestMetric.preSuggest();
    long startTime = System.nanoTime();
    XContentParser parser = null;
    try (Engine.Searcher searcher = indexShard.acquireSearcher("suggest")) {
        BytesReference suggest = request.suggest();
        if (suggest != null && suggest.length() > 0) {
            parser = XContentFactory.xContent(suggest).createParser(suggest);
            if (parser.nextToken() != XContentParser.Token.START_OBJECT) {
                throw new IllegalArgumentException("suggest content missing");
            }
            final SuggestionSearchContext context = suggestPhase.parseElement().parseInternal(parser, indexService.mapperService(),
                    indexService.queryParserService(), request.shardId().getIndex(), request.shardId().id(), request);
            final Suggest result = suggestPhase.execute(context, searcher.searcher());
            return new ShardSuggestResponse(request.shardId(), result);
        }
        return new ShardSuggestResponse(request.shardId(), new Suggest());
    } catch (Throwable ex) {
        throw new ElasticsearchException("failed to execute suggest", ex);
    } finally {
        if (parser != null) {
            parser.close();
        }
        suggestMetric.postSuggest(System.nanoTime() - startTime);
    }
}
 
Example 16
Source File: ExportParser.java    From elasticsearch-inout-plugin with Apache License 2.0 5 votes vote down vote up
/**
 * Main method of this class to parse given payload of _export action
 *
 * @param context
 * @param source
 * @throws SearchParseException
 */
public void parseSource(ExportContext context, BytesReference source) throws SearchParseException {
    XContentParser parser = null;
    try {
        if (source != null && source.length() != 0) {
            parser = XContentFactory.xContent(source).createParser(source);
            XContentParser.Token token;
            while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
                if (token == XContentParser.Token.FIELD_NAME) {
                    String fieldName = parser.currentName();
                    parser.nextToken();
                    SearchParseElement element = elementParsers.get(fieldName);
                    if (element == null) {
                        throw new SearchParseException(context, "No parser for element [" + fieldName + "]");
                    }
                    element.parse(parser, context);
                } else if (token == null) {
                    break;
                }
            }
        }
        validate(context);
    } catch (Exception e) {
        String sSource = "_na_";
        try {
            sSource = XContentHelper.convertToJson(source, false);
        } catch (Throwable e1) {
            // ignore
        }
        throw new SearchParseException(context, "Failed to parse source [" + sSource + "]", e);
    } finally {
        if (parser != null) {
            parser.close();
        }
    }
}
 
Example 17
Source File: TransportTermsByQueryAction.java    From siren-join with GNU Affero General Public License v3.0 4 votes vote down vote up
/**
 * The operation that executes the query and generates a {@link TermsByQueryShardResponse} for each shard.
 */
@Override
protected TermsByQueryShardResponse shardOperation(TermsByQueryShardRequest shardRequest) throws ElasticsearchException {
  IndexService indexService = indicesService.indexServiceSafe(shardRequest.shardId().getIndex());
  IndexShard indexShard = indexService.shardSafe(shardRequest.shardId().id());
  TermsByQueryRequest request = shardRequest.request();
  OrderByShardOperation orderByOperation = OrderByShardOperation.get(request.getOrderBy(), request.maxTermsPerShard());

  SearchShardTarget shardTarget = new SearchShardTarget(clusterService.localNode().id(),
                                                        shardRequest.shardId().getIndex(),
                                                        shardRequest.shardId().id());

  ShardSearchRequest shardSearchRequest = new ShardSearchLocalRequest(request.types(), request.nowInMillis(),
                                                                      shardRequest.filteringAliases());

  SearchContext context = new DefaultSearchContext(0, shardSearchRequest, shardTarget,
    indexShard.acquireSearcher("termsByQuery"), indexService, indexShard, scriptService,
    pageCacheRecycler, bigArrays, threadPool.estimatedTimeInMillisCounter(), parseFieldMatcher,
    SearchService.NO_TIMEOUT);
  SearchContext.setCurrent(context);

  try {
    MappedFieldType fieldType = context.smartNameFieldType(request.field());
    if (fieldType == null) {
      throw new SearchContextException(context, "[termsByQuery] field '" + request.field() +
              "' not found for types " + Arrays.toString(request.types()));
    }

    IndexFieldData indexFieldData = context.fieldData().getForField(fieldType);

    BytesReference querySource = request.querySource();
    if (querySource != null && querySource.length() > 0) {
      XContentParser queryParser = null;
      try {
        queryParser = XContentFactory.xContent(querySource).createParser(querySource);
        QueryParseContext.setTypes(request.types());
        ParsedQuery parsedQuery = orderByOperation.getParsedQuery(queryParser, indexService);
        if (parsedQuery != null) {
          context.parsedQuery(parsedQuery);
        }
      }
      finally {
        QueryParseContext.removeTypes();
        if (queryParser != null) {
          queryParser.close();
        }
      }
    }

    context.preProcess();

    // execute the search only gathering the hit count and bitset for each segment
    logger.debug("{}: Executes search for collecting terms {}", Thread.currentThread().getName(),
      shardRequest.shardId());

    TermsCollector termsCollector = this.getTermsCollector(request.termsEncoding(), indexFieldData, context);
    if (request.expectedTerms() != null) termsCollector.setExpectedTerms(request.expectedTerms());
    if (request.maxTermsPerShard() != null) termsCollector.setMaxTerms(request.maxTermsPerShard());
    HitStream hitStream = orderByOperation.getHitStream(context);
    TermsSet terms = termsCollector.collect(hitStream);

    logger.debug("{}: Returns terms response with {} terms for shard {}", Thread.currentThread().getName(),
      terms.size(), shardRequest.shardId());

    return new TermsByQueryShardResponse(shardRequest.shardId(), terms);
  }
  catch (Throwable e) {
    logger.error("[termsByQuery] Error executing shard operation", e);
    throw new QueryPhaseExecutionException(context, "[termsByQuery] Failed to execute query", e);
  }
  finally {
    // this will also release the index searcher
    context.close();
    SearchContext.removeCurrent();
  }
}
 
Example 18
Source File: DumpParser.java    From elasticsearch-inout-plugin with Apache License 2.0 4 votes vote down vote up
/**
 * Main method of this class to parse given payload of _dump action
 *
 * @param context
 * @param source
 * @throws SearchParseException
 */
public void parseSource(ExportContext context, BytesReference source) throws SearchParseException {
    XContentParser parser = null;
    this.setDefaults(context);
    try {
        if (source != null && source.length() != 0) {
            parser = XContentFactory.xContent(source).createParser(source);
            XContentParser.Token token;
            while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
                if (token == XContentParser.Token.FIELD_NAME) {
                    String fieldName = parser.currentName();
                    parser.nextToken();
                    SearchParseElement element = elementParsers.get(fieldName);
                    if (element == null) {
                        throw new SearchParseException(context, "No parser for element [" + fieldName + "]");
                    }
                    element.parse(parser, context);
                } else if (token == null) {
                    break;
                }
            }
        }
        if (context.outputFile() == null) {
            directoryParseElement.setOutPutFile(context, DEFAULT_DIR);
            this.ensureDefaultDirectory(context);
        }
        context.mappings(true);
        context.settings(true);
    } catch (Exception e) {
        String sSource = "_na_";
        try {
            sSource = XContentHelper.convertToJson(source, false);
        } catch (Throwable e1) {
            // ignore
        }
        throw new SearchParseException(context, "Failed to parse source [" + sSource + "]", e);
    } finally {
        if (parser != null) {
            parser.close();
        }
    }
}
 
Example 19
Source File: SearchService.java    From Elasticsearch with Apache License 2.0 4 votes vote down vote up
private void parseSource(SearchContext context, BytesReference source) throws SearchParseException {
    // nothing to parse...
    if (source == null || source.length() == 0) {
        return;
    }
    String abc = source.toUtf8();
    XContentParser parser = null;
    try {
        parser = XContentFactory.xContent(source).createParser(source);
        XContentParser.Token token;
        token = parser.nextToken();
        if (token != XContentParser.Token.START_OBJECT) {
            throw new ElasticsearchParseException("failed to parse search source. source must be an object, but found [{}] instead", token.name());
        }
        while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
            if (token == XContentParser.Token.FIELD_NAME) {
                String fieldName = parser.currentName();
                parser.nextToken();
                SearchParseElement element = elementParsers.get(fieldName);
                if (element == null) {
                    throw new SearchParseException(context, "failed to parse search source. unknown search element [" + fieldName + "]", parser.getTokenLocation());
                }
                element.parse(parser, context);
            } else {
                if (token == null) {
                    throw new ElasticsearchParseException("failed to parse search source. end of query source reached but query is not complete.");
                } else {
                    throw new ElasticsearchParseException("failed to parse search source. expected field name but got [{}]", token);
                }
            }
        }
    } catch (Throwable e) {
        String sSource = "_na_";
        try {
            sSource = XContentHelper.convertToJson(source, false);
        } catch (Throwable e1) {
            // ignore
        }
        XContentLocation location = parser != null ? parser.getTokenLocation() : null;
        throw new SearchParseException(context, "failed to parse search source [" + sSource + "]", location, e);
    } finally {
        if (parser != null) {
            parser.close();
        }
    }
}
 
Example 20
Source File: RestoreParser.java    From elasticsearch-inout-plugin with Apache License 2.0 4 votes vote down vote up
/**
 * Main method of this class to parse given payload of _restore action
 *
 * @param context
 * @param source
 * @throws org.elasticsearch.search.SearchParseException
 */
public void parseSource(ImportContext context, BytesReference source) throws ImportParseException {
    XContentParser parser = null;
    this.setDefaults(context);
    context.settings(true);
    context.mappings(true);
    try {
        if (source != null && source.length() != 0) {
            parser = XContentFactory.xContent(source).createParser(source);
            XContentParser.Token token;
            while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
                if (token == XContentParser.Token.FIELD_NAME) {
                    String fieldName = parser.currentName();
                    parser.nextToken();
                    ImportParseElement element = elementParsers.get(fieldName);
                    if (element == null) {
                        throw new ImportParseException(context, "No parser for element [" + fieldName + "]");
                    }
                    element.parse(parser, context);
                } else if (token == null) {
                    break;
                }
            }
        }
        if (context.directory() == null) {
            context.directory(DumpParser.DEFAULT_DIR);
        }
    } catch (Exception e) {
        String sSource = "_na_";
        try {
            sSource = XContentHelper.convertToJson(source, false);
        } catch (Throwable e1) {
            // ignore
        }
        throw new ImportParseException(context, "Failed to parse source [" + sSource + "]", e);
    } finally {
        if (parser != null) {
            parser.close();
        }
    }
}