001package org.hl7.fhir.utilities;
002
003/*
004  Copyright (c) 2011+, HL7, Inc.
005  All rights reserved.
006  
007  Redistribution and use in source and binary forms, with or without modification, 
008  are permitted provided that the following conditions are met:
009    
010   * Redistributions of source code must retain the above copyright notice, this 
011     list of conditions and the following disclaimer.
012   * Redistributions in binary form must reproduce the above copyright notice, 
013     this list of conditions and the following disclaimer in the documentation 
014     and/or other materials provided with the distribution.
015   * Neither the name of HL7 nor the names of its contributors may be used to 
016     endorse or promote products derived from this software without specific 
017     prior written permission.
018  
019  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
020  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
021  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
022  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
023  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
024  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
025  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
026  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
027  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
028  POSSIBILITY OF SUCH DAMAGE.
029  
030 */
031
032
033
034import org.hl7.fhir.exceptions.FHIRException;
035
036/**
037 * This object processes a string that contains <%%> or [%%] where each of these 
038 * represents a 'command' that either does something, or inserts content into the
039 * string - which is then reprocessed 
040 * 
041 * The outcome is a string. 
042 * 
043 * This is a base class that is expected to be subclassed for various context
044 * specific processors
045 * 
046 * @author Grahame Grieve
047 *
048 */
049public abstract class ScriptedPageProcessor {
050
051  protected String title;
052  protected int level;
053  
054  public ScriptedPageProcessor(String title, int level) {
055    super();
056    this.title = title;
057    this.level = level;
058  }
059
060  public String process(String content) throws Exception {
061    StringBuilder outcome = new StringBuilder();
062    int cursor = 0;
063    while (cursor < content.length()) {
064      if (nextIs(content, cursor, "[%")) {
065        cursor = processEntry(outcome, content, cursor, "%]");
066      } else if (nextIs(content, cursor, "<%")) {
067        cursor = processEntry(outcome, content, cursor, "%>");        
068      } else {
069        outcome.append(content.charAt(cursor));
070        cursor++;
071      }
072    }
073    return outcome.toString();
074  }
075
076  private int processEntry(StringBuilder outcome, String content, int cursor, String endText) throws Exception {
077    int start = cursor+endText.length();
078    int end = start;
079    while (end < content.length()) {
080      if (nextIs(content, end, endText)) {
081        outcome.append(process(getContent(content.substring(start, end))));
082        return end+endText.length();
083      }
084      end++;
085    }
086    throw new FHIRException("unterminated insert sequence");
087  }
088
089  private String getContent(String command) throws Exception {
090    if (Utilities.noString(command) || command.startsWith("!"))
091      return "";
092    
093    String[] parts = command.split("\\ ");
094    return processCommand(command, parts);
095  }
096
097  protected String processCommand(String command, String[] com) throws Exception {
098    if (com[0].equals("title"))
099      return title;
100    else if (com[0].equals("xtitle"))
101      return Utilities.escapeXml(title);
102    else if (com[0].equals("level"))
103      return genlevel();  
104    else if (com[0].equals("settitle")) {
105      title = command.substring(9).replace("{", "<%").replace("}", "%>");
106      return "";
107    }
108    else
109      throw new FHIRException("Unknown command "+com[0]);
110  }
111
112  private boolean nextIs(String content, int cursor, String value) {
113    if (cursor + value.length() > content.length())
114      return false;
115    else {
116      String v = content.substring(cursor, cursor+value.length());
117      return v.equals(value);
118    }
119  }
120 
121  public String genlevel() {
122    StringBuilder b = new StringBuilder();
123    for (int i = 0; i < level; i++) {
124      b.append("../");
125    }
126    return b.toString();
127  }
128
129
130}