001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache license, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the license for the specific language governing permissions and 015 * limitations under the license. 016 */ 017package org.apache.logging.log4j.core.script; 018 019import java.io.File; 020import java.io.FileInputStream; 021import java.io.IOException; 022import java.io.InputStreamReader; 023import java.io.Reader; 024import java.net.URI; 025import java.nio.charset.Charset; 026import java.nio.file.Path; 027import java.nio.file.Paths; 028 029import org.apache.logging.log4j.Logger; 030import org.apache.logging.log4j.core.config.Node; 031import org.apache.logging.log4j.core.config.plugins.Plugin; 032import org.apache.logging.log4j.core.config.plugins.PluginAttribute; 033import org.apache.logging.log4j.core.config.plugins.PluginFactory; 034import org.apache.logging.log4j.core.util.ExtensionLanguageMapping; 035import org.apache.logging.log4j.core.util.FileUtils; 036import org.apache.logging.log4j.core.util.IOUtils; 037import org.apache.logging.log4j.core.util.NetUtils; 038import org.apache.logging.log4j.status.StatusLogger; 039 040/** 041 * Container for the language and body of a script file along with the file location. 042 */ 043@Plugin(name = "ScriptFile", category = Node.CATEGORY, printObject = true) 044public class ScriptFile extends AbstractScript { 045 046 private static final Logger LOGGER = StatusLogger.getLogger(); 047 private final Path filePath; 048 private final boolean isWatched; 049 050 051 public ScriptFile(String name, Path filePath, String language, boolean isWatched, String scriptText) { 052 super(name, language, scriptText); 053 this.filePath = filePath; 054 this.isWatched = isWatched; 055 } 056 057 public Path getPath() { 058 return this.filePath; 059 } 060 061 public boolean isWatched() { 062 return isWatched; 063 } 064 065 @PluginFactory 066 public static ScriptFile createScript( 067 // @formatter:off 068 @PluginAttribute("name") String name, 069 @PluginAttribute("language") String language, 070 @PluginAttribute("path") final String filePathOrUri, 071 @PluginAttribute("isWatched") final Boolean isWatched, 072 @PluginAttribute("charset") final Charset charset) { 073 // @formatter:on 074 if (filePathOrUri == null) { 075 LOGGER.error("No script path provided for ScriptFile"); 076 return null; 077 } 078 if (name == null) { 079 name = filePathOrUri; 080 } 081 final URI uri = NetUtils.toURI(filePathOrUri); 082 final File file = FileUtils.fileFromUri(uri); 083 if (language == null && file != null) { 084 String fileExtension = FileUtils.getFileExtension(file); 085 if (fileExtension != null) { 086 ExtensionLanguageMapping mapping = ExtensionLanguageMapping.getByExtension(fileExtension); 087 if (mapping != null) { 088 language = mapping.getLanguage(); 089 } 090 } 091 } 092 if (language == null) { 093 LOGGER.info("No script language supplied, defaulting to {}", DEFAULT_LANGUAGE); 094 language = DEFAULT_LANGUAGE; 095 } 096 097 final Charset actualCharset = charset == null ? Charset.defaultCharset() : charset; 098 String scriptText; 099 try (final Reader reader = new InputStreamReader( 100 file != null ? new FileInputStream(file) : uri.toURL().openStream(), actualCharset)) { 101 scriptText = IOUtils.toString(reader); 102 } catch (IOException e) { 103 LOGGER.error("{}: language={}, path={}, actualCharset={}", e.getClass().getSimpleName(), 104 language, filePathOrUri, actualCharset); 105 return null; 106 } 107 Path path = file != null ? Paths.get(file.toURI()) : Paths.get(uri); 108 if (path == null) { 109 LOGGER.error("Unable to convert {} to a Path", uri.toString()); 110 return null; 111 } 112 return new ScriptFile(name, path, language, isWatched == null ? Boolean.FALSE : isWatched, scriptText); 113 } 114 115 @Override 116 public String toString() { 117 StringBuilder sb = new StringBuilder(); 118 if (!(getName().equals(filePath.toString()))) { 119 sb.append("name=").append(getName()).append(", "); 120 } 121 sb.append("path=").append(filePath); 122 if (getLanguage() != null) { 123 sb.append(", language=").append(getLanguage()); 124 } 125 sb.append(", isWatched=").append(isWatched); 126 return sb.toString(); 127 } 128}