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