001package org.hl7.fhir.utilities;
002
003/*-
004 * #%L
005 * org.hl7.fhir.utilities
006 * %%
007 * Copyright (C) 2014 - 2019 Health Level 7
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 * 
013 *      http://www.apache.org/licenses/LICENSE-2.0
014 * 
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023
024import org.hl7.fhir.exceptions.FHIRException;
025
026/**
027 * This object processes a string that contains <%%> or [%%] where each of these 
028 * represents a 'command' that either does something, or inserts content into the
029 * string - which is then reprocessed 
030 * 
031 * The outcome is a string. 
032 * 
033 * This is a base class that is expected to be subclassed for various context
034 * specific processors
035 * 
036 * @author Grahame Grieve
037 *
038 */
039public abstract class ScriptedPageProcessor {
040
041  protected String title;
042  protected int level;
043  
044  public ScriptedPageProcessor(String title, int level) {
045    super();
046    this.title = title;
047    this.level = level;
048  }
049
050  public String process(String content) throws Exception {
051    StringBuilder outcome = new StringBuilder();
052    int cursor = 0;
053    while (cursor < content.length()) {
054      if (nextIs(content, cursor, "[%")) {
055        cursor = processEntry(outcome, content, cursor, "%]");
056      } else if (nextIs(content, cursor, "<%")) {
057        cursor = processEntry(outcome, content, cursor, "%>");        
058      } else {
059        outcome.append(content.charAt(cursor));
060        cursor++;
061      }
062    }
063    return outcome.toString();
064  }
065
066  private int processEntry(StringBuilder outcome, String content, int cursor, String endText) throws Exception {
067    int start = cursor+endText.length();
068    int end = start;
069    while (end < content.length()) {
070      if (nextIs(content, end, endText)) {
071        outcome.append(process(getContent(content.substring(start, end))));
072        return end+endText.length();
073      }
074      end++;
075    }
076    throw new FHIRException("unterminated insert sequence");
077  }
078
079  private String getContent(String command) throws Exception {
080    if (Utilities.noString(command) || command.startsWith("!"))
081      return "";
082    
083    String[] parts = command.split("\\ ");
084    return processCommand(command, parts);
085  }
086
087  protected String processCommand(String command, String[] com) throws Exception {
088    if (com[0].equals("title"))
089      return title;
090    else if (com[0].equals("xtitle"))
091      return Utilities.escapeXml(title);
092    else if (com[0].equals("level"))
093      return genlevel();  
094    else if (com[0].equals("settitle")) {
095      title = command.substring(9).replace("{", "<%").replace("}", "%>");
096      return "";
097    }
098    else
099      throw new FHIRException("Unknown command "+com[0]);
100  }
101
102  private boolean nextIs(String content, int cursor, String value) {
103    if (cursor + value.length() > content.length())
104      return false;
105    else {
106      String v = content.substring(cursor, cursor+value.length());
107      return v.equals(value);
108    }
109  }
110 
111  public String genlevel() {
112    StringBuilder b = new StringBuilder();
113    for (int i = 0; i < level; i++) {
114      b.append("../");
115    }
116    return b.toString();
117  }
118
119
120}
121