1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * See LICENSE.txt included in this distribution for the specific 9 * language governing permissions and limitations under the License. 10 * 11 * When distributing Covered Code, include this CDDL HEADER in each 12 * file and include the License file at LICENSE.txt. 13 * If applicable, add the following below this CDDL HEADER, with the 14 * fields enclosed by brackets "[]" replaced with your own identifying 15 * information: Portions Copyright [yyyy] [name of copyright owner] 16 * 17 * CDDL HEADER END 18 */ 19 20 /* 21 * Copyright (c) 2018, Chris Fraire <cfraire@me.com>. 22 */ 23 24 package org.opengrok.indexer.web; 25 26 import java.io.Writer; 27 import org.opengrok.indexer.configuration.RuntimeEnvironment; 28 %% 29 %public 30 %class XrefSourceTransformer 31 %unicode 32 %type boolean 33 %eofval{ 34 return false; 35 %eofval} 36 %{ 37 private static final String SOURCE = "source"; 38 private static final String SOURCE1 = "/" + SOURCE; 39 private static final String SOURCE2 = SOURCE1 + "/"; 40 private static final String HREF_EQ_QUOT = "href=\""; 41 private static final String HREF_EQ_QSOURCE2 = HREF_EQ_QUOT + SOURCE2; 42 43 private Writer out; 44 45 /** 46 * If set, this will have a leading and trailing slash (which might be the 47 * same character for the root path). It's intended to substitute the 48 * default {@code "/source/"} from 49 * {@link RuntimeEnvironment#getUrlPrefix()}. 50 */ 51 private String contextPath; 52 53 /** 54 * Sets the required target to write. 55 * @param out a required instance 56 */ setWriter(Writer out)57 public void setWriter(Writer out) { 58 if (out == null) { 59 throw new IllegalArgumentException("`out' is null"); 60 } 61 this.out = out; 62 } 63 64 /** 65 * Sets the optional context path override. 66 * @param path an optional instance 67 */ setContextPath(String path)68 public void setContextPath(String path) { 69 if (path == null || path.equals(SOURCE) || path.equals(SOURCE1) || 70 path.equals(SOURCE2)) { 71 this.contextPath = null; 72 } else { 73 StringBuilder pathBuilder = new StringBuilder(); 74 75 if (!path.startsWith("/")) { 76 pathBuilder.append("/"); 77 } 78 pathBuilder.append(path); 79 this.contextPath = pathBuilder.toString(); 80 81 if (!this.contextPath.endsWith("/")) { 82 pathBuilder.append("/"); 83 this.contextPath = pathBuilder.toString(); 84 } 85 } 86 } 87 %} 88 89 %% 90 91 /* 92 * Matches a hyperlink to the static OpenGrok urlPrefix for possible 93 * substitution. 94 */ 95 "href=\"/source/" { 96 if (contextPath == null) { 97 out.write(HREF_EQ_QSOURCE2); // faster than yytext() 98 } else { 99 out.write(HREF_EQ_QUOT); 100 out.write(contextPath); 101 } 102 } 103 104 [^] { 105 for (int i = 0; i < yylength(); ++i) { 106 out.write(yycharat(i)); // faster than yytext() 107 } 108 } 109