001package org.hl7.fhir.utilities;
002
003import org.hl7.fhir.exceptions.FHIRException;
004
005/**
006 * This object processes a string that contains <%%> or [%%] where each of these 
007 * represents a 'command' that either does something, or inserts content into the
008 * string - which is then reprocessed 
009 * 
010 * The outcome is a string. 
011 * 
012 * This is a base class that is expected to be subclassed for various context
013 * specific processors
014 * 
015 * @author Grahame Grieve
016 *
017 */
018public abstract class ScriptedPageProcessor {
019
020  protected String title;
021  protected int level;
022  
023  public ScriptedPageProcessor(String title, int level) {
024    super();
025    this.title = title;
026    this.level = level;
027  }
028
029  public String process(String content) throws Exception {
030    StringBuilder outcome = new StringBuilder();
031    int cursor = 0;
032    while (cursor < content.length()) {
033      if (nextIs(content, cursor, "[%")) {
034        cursor = processEntry(outcome, content, cursor, "%]");
035      } else if (nextIs(content, cursor, "<%")) {
036        cursor = processEntry(outcome, content, cursor, "%>");        
037      } else {
038        outcome.append(content.charAt(cursor));
039        cursor++;
040      }
041    }
042    return outcome.toString();
043  }
044
045  private int processEntry(StringBuilder outcome, String content, int cursor, String endText) throws Exception {
046    int start = cursor+endText.length();
047    int end = start;
048    while (end < content.length()) {
049      if (nextIs(content, end, endText)) {
050        outcome.append(process(getContent(content.substring(start, end))));
051        return end+endText.length();
052      }
053      end++;
054    }
055    throw new FHIRException("unterminated insert sequence");
056  }
057
058  private String getContent(String command) throws Exception {
059    if (Utilities.noString(command) || command.startsWith("!"))
060      return "";
061    
062    String[] parts = command.split("\\ ");
063    return processCommand(command, parts);
064  }
065
066  protected String processCommand(String command, String[] com) throws Exception {
067    if (com[0].equals("title"))
068      return title;
069    else if (com[0].equals("xtitle"))
070      return Utilities.escapeXml(title);
071    else if (com[0].equals("level"))
072      return genlevel();  
073    else if (com[0].equals("settitle")) {
074      title = command.substring(9).replace("{", "<%").replace("}", "%>");
075      return "";
076    }
077    else
078      throw new FHIRException("Unknown command "+com[0]);
079  }
080
081  private boolean nextIs(String content, int cursor, String value) {
082    if (cursor + value.length() > content.length())
083      return false;
084    else {
085      String v = content.substring(cursor, cursor+value.length());
086      return v.equals(value);
087    }
088  }
089 
090  public String genlevel() {
091    StringBuilder b = new StringBuilder();
092    for (int i = 0; i < level; i++) {
093      b.append("../");
094    }
095    return b.toString();
096  }
097
098
099}
100