Как бы мне перебрать список [[токенов]] и заменить их вводом в текстовое поле? - PullRequest
1 голос
/ 19 января 2010

Вот основной код, который я пытаюсь заставить работать:

Field fields[] = SalesLetter.class.getDeclaredFields();
String fieldName;

for (int j = 0, m = fields.length; j < m; j++) {
       fieldName = fields[j].getName(); //example fieldname [[headline]]
       templateHTML = templateHTML.replace(fieldName, Letter.fieldName());
}

Я полагаю, что ошибаюсь, пытаясь получить getDeclaredFields (что даже синтаксически неверно). Когда я закончил свою работу, у меня возникло несколько вопросов о стековом потоке, которые я прочитал перед написанием этого. Они были:

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

Это дало мне идею прочитать все допустимые [[токены]] из текстового файла, поместить их в хеш (я имею в виду map, это java: D), а затем создать ссылку на объект с тем же именем, что и этот знак.

Я не могу понять, как бы я сделал такую ​​вещь конкретно в Java, или если это сработало бы. Пожалуйста, помогите.

Заранее спасибо,

Коди Гудман

Примечание: я пытаюсь сделать все максимально гибким, поэтому, возможно, в будущем я мог бы добавить такие вещи, как "[[tokenname]]: это имя токена, вам нужно действительно подумать о том, что хочет клиент чтобы найти хорошее имя токена "в текстовом файле, тогда эти поля генерируются в моей форме, и все работает:)

Ответы [ 2 ]

1 голос
/ 19 января 2010

Чтобы прочитать значения из нестатических полей типа, вам понадобится ссылка на экземпляр типа:

public class ReflectFields {
  static class Letter {
    public int baz = 100;
  }

  static class SalesLetter extends Letter {
    public String foo = "bar";
  }

  public static void main(String[] args) throws Exception {
    // TODO: better exception handling, etc.
    SalesLetter instance = new SalesLetter();
    for (Field field : instance.getClass().getFields()) {
      System.out.format("%s = %s%n", field.getName(), field.get(instance));
    }
  }
}

Вам также придется следить за закрытыми полями,и т. д. В общем, этого подхода следует избегать, так как он нарушает инкапсуляцию, рассматривая внутренние компоненты класса.

Рассмотрите возможность использования API JavaBean.

public class BeanHelper {
  private final Object bean;
  private final Map<String, Method> getters = new TreeMap<String, Method>();

  public BeanHelper(Object bean) {
    this.bean = bean;
    for (PropertyDescriptor pd : Introspector.getBeanInfo(bean.getClass(),
          Object.class).getPropertyDescriptors()) {
      getters.put(pd.getName(), pd.getReadMethod());
    }
  }

  public Set<String> getProperties() { return getters.keySet(); }

  public Object get(String propertyName) {
    return getters.get(propertyName).invoke(bean);
  }

  public static void main(String[] args) {
    BeanHelper helper = new BeanHelper(new MyBean());
    for (String prop : helper.getProperties()) {
      System.out.format("%s = %s%n", prop, helper.get(prop));
    }
  }

  public static class MyBean {
    private final String foo = "bar";
    private final boolean baz = true;
    public String getFoo() { return foo; }
    public boolean isBaz() { return baz; }
  }
}

Для краткости обработка исключений исключена, поэтомувам нужно добавить несколько блоков try / catch (я предлагаю обернуть перехваченные исключения в IllegalStateException s).

0 голосов
/ 19 января 2010

Как насчет использования шаблонизатора, такого как Freemarker , Скорость или StringTemplate :

  • заменить [[ на ${ и ]] на }
  • создать модель из файла свойств, содержащего замены
  • шаблон процесса HTML

Вот пример с Freemarker (без обработки исключений)

Configuration config = new Configuration();
StringTemplateLoader loader = new StringTemplateLoader();
config.setTeplateLoader(loader);

Map model = Properites.load(new FileInputStream("tokens.properties"));
loader.putTemplate("html.ftl", templateHTML);
Template template = config.getTemplate("html.ftl");

Writer out = new StringWriter();
template.process(root, out);
String result = out.toString();

StringTemplate может быть более простым (замените [[ и ]] на $), но я не похож на него:

Map model = Properites.load(new FileInputStream("tokens.properties"));
StringTemplate template = new StringTemplate(templateHTML);
template.setAttributes(model);
String result = template.toString();

Файл tokens.properties выглядит следующим образом:

tokenname:this is token name
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...