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.core.config.Node; 030import org.apache.logging.log4j.core.config.plugins.Plugin; 031import org.apache.logging.log4j.core.config.plugins.PluginAttribute; 032import org.apache.logging.log4j.core.config.plugins.PluginFactory; 033import org.apache.logging.log4j.core.util.ExtensionLanguageMapping; 034import org.apache.logging.log4j.core.util.FileUtils; 035import org.apache.logging.log4j.core.util.IOUtils; 036import org.apache.logging.log4j.core.util.NetUtils; 037 038/** 039 * Container for the language and body of a script file along with the file location. 040 */ 041@Plugin(name = "ScriptFile", category = Node.CATEGORY, printObject = true) 042public class ScriptFile extends AbstractScript { 043 044 private final Path filePath; 045 private final boolean isWatched; 046 047 048 public ScriptFile(final String name, final Path filePath, final String language, final boolean isWatched, final String scriptText) { 049 super(name, language, scriptText); 050 this.filePath = filePath; 051 this.isWatched = isWatched; 052 } 053 054 public Path getPath() { 055 return this.filePath; 056 } 057 058 public boolean isWatched() { 059 return isWatched; 060 } 061 062 @PluginFactory 063 public static ScriptFile createScript( 064 // @formatter:off 065 @PluginAttribute("name") String name, 066 @PluginAttribute("language") String language, 067 @PluginAttribute("path") final String filePathOrUri, 068 @PluginAttribute("isWatched") final Boolean isWatched, 069 @PluginAttribute("charset") final Charset charset) { 070 // @formatter:on 071 if (filePathOrUri == null) { 072 LOGGER.error("No script path provided for ScriptFile"); 073 return null; 074 } 075 if (name == null) { 076 name = filePathOrUri; 077 } 078 final URI uri = NetUtils.toURI(filePathOrUri); 079 final File file = FileUtils.fileFromUri(uri); 080 if (language == null && file != null) { 081 final String fileExtension = FileUtils.getFileExtension(file); 082 if (fileExtension != null) { 083 final ExtensionLanguageMapping mapping = ExtensionLanguageMapping.getByExtension(fileExtension); 084 if (mapping != null) { 085 language = mapping.getLanguage(); 086 } 087 } 088 } 089 if (language == null) { 090 LOGGER.info("No script language supplied, defaulting to {}", DEFAULT_LANGUAGE); 091 language = DEFAULT_LANGUAGE; 092 } 093 094 final Charset actualCharset = charset == null ? Charset.defaultCharset() : charset; 095 String scriptText; 096 try (final Reader reader = new InputStreamReader( 097 file != null ? new FileInputStream(file) : uri.toURL().openStream(), actualCharset)) { 098 scriptText = IOUtils.toString(reader); 099 } catch (final IOException e) { 100 LOGGER.error("{}: language={}, path={}, actualCharset={}", e.getClass().getSimpleName(), 101 language, filePathOrUri, actualCharset); 102 return null; 103 } 104 final Path path = file != null ? Paths.get(file.toURI()) : Paths.get(uri); 105 if (path == null) { 106 LOGGER.error("Unable to convert {} to a Path", uri.toString()); 107 return null; 108 } 109 return new ScriptFile(name, path, language, isWatched == null ? Boolean.FALSE : isWatched, scriptText); 110 } 111 112 @Override 113 public String toString() { 114 final StringBuilder sb = new StringBuilder(); 115 if (!(getName().equals(filePath.toString()))) { 116 sb.append("name=").append(getName()).append(", "); 117 } 118 sb.append("path=").append(filePath); 119 if (getLanguage() != null) { 120 sb.append(", language=").append(getLanguage()); 121 } 122 sb.append(", isWatched=").append(isWatched); 123 return sb.toString(); 124 } 125}