Как я могу упростить этот метод анализа? - PullRequest
0 голосов
/ 18 апреля 2019

Я пишу код для демонтажа XML из файла.Я не знаю заранее, на какой схеме основан XML, поэтому я пытаюсь разобрать его с помощью нескольких схем в виде различных экземпляров Jaxb2Marshaller.

Метод должен:

  1. попытка разархивировать XML с каждым маршаллером
  2. Если это удастся, вернуть полученный объект
  3. Если не получится, попробуйте следующий маршаллер
  4. Если все маршаллеры не пройдены, выведитеисключение с последним сообщением об ошибке

Вот текущий код:

private Object getObject(final byte[] data) throws MyException {
    String lastErrorMessage = "";
    for (final Jaxb2Marshaller marshaller : this.marshallers) {
        try {
            return marshaller.unmarshal(new StreamSource(new ByteArrayInputStream(data)));
        } catch (final XmlMappingException e) {
            LOGGER.warn("Invalid XML", e);
            lastErrorMessage = e.getMessage();
        }
    }
    throw new MyException(lastErrorMessage);
}

Мне кажется, что этот метод делает слишком много вещей на разных уровнях абстракции:

  • перебрать маршаллеры
  • применить маршаллер
  • результат возврата
  • перехват исключений
  • исключение выброса

Но яне вижу способа упростить это.Блок try-catch необходим для каждого маршаллера (потому что я должен ловить и игнорировать эти исключения XmlMappingException, кроме последнего).Этот блок либо возвращает объект результата, либо lastErrorMessage, который необходим ниже итерации для выброса MyException.

Единственное решение, которое я могу придумать, - это создать какой-то придуманный класс Result, который содержит либо объект результата, либосообщение об ошибке, но это кажется грязным.Любые другие идеи?

1 Ответ

0 голосов
/ 19 апреля 2019

Я хотел бы, чтобы методы с гранулярностью были такими:

private Object getObject(byte[] data) throws MyException {
    Result result;
    for (Jaxb2Marshaller marshaller : this.marshallers) {
        result = getObject(marshaller, data);
    }
    return handleError(result);
}

private Result getObject(Jaxb2Marshaller marshaller, byte[] data) {
    try {
        return Result.value(marshaller.unmarshal(new StreamSource(new ByteArrayInputStream(data))));
    } catch (final XmlMappingException e) {
        LOGGER.warn("Invalid XML", e);
        return Result.error(e.getMessage());
    }
}

private Object handleError(Result result) {
    if (result.isError()) {
        throw new MyException(result.errroMessage);
    }
    else {
        return result.value;        
    }
}

Но дополнительный класс Result является многословным и громоздким:

private class Result {
    String errorMessage;
    Object value;

    static Result error(String errorMessage) {
        Result result = new Result();
        result.errorMessage = errorMessage;
        return result;
    }

    static Result value(Object value) {
        Result result = new Result();
        result.value = value;
        return result;
    }

    boolean isError() {
        return errorMessage != null;
    }
}
...