001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.commons.weaver.ant; 020 021import java.io.File; 022import java.util.Arrays; 023import java.util.List; 024import java.util.Map; 025import java.util.Properties; 026 027import org.apache.commons.lang3.StringUtils; 028import org.apache.tools.ant.BuildException; 029import org.apache.tools.ant.Project; 030import org.apache.tools.ant.types.DataType; 031import org.apache.tools.ant.types.EnumeratedAttribute; 032import org.apache.tools.ant.types.Path; 033import org.apache.tools.ant.types.PropertySet; 034import org.apache.tools.ant.types.Reference; 035import org.apache.tools.ant.types.PropertySet.BuiltinPropertySetName; 036 037/** 038 * Standalone weaver settings datatype. Handles: 039 * <ul> 040 * <li>{@code target} attribute - {@link File}</li> 041 * <li>{@code classpath} attribute - {@link Path} (incompatible with {@code classpathref})</li> 042 * <li>{@code classpathref} attribute - {@link String} (incompatible with {@code classpath})</li> 043 * <li>{@code includeSystemClasspath} attribute - {@code boolean}</li> 044 * <li>nested {@code propertyset} - {@link PropertySet}</li> 045 * <li>nested {@code properties} - {@link InlineProperties}</li> 046 * </ul> 047 * {@code propertyset} and {@code properties} are merged, with the latter taking precedence. 048 */ 049public class WeaverSettings extends DataType { 050 private File target; 051 private Path classpath; 052 private String classpathref; 053 private PropertySet propertySet; 054 private InlineProperties inlineProperties; 055 private boolean includeSystemClasspath; 056 057 /** 058 * Create a new {@link WeaverSettings} object. 059 * @param project owner 060 */ 061 public WeaverSettings(final Project project) { 062 super(); 063 setProject(project); 064 } 065 066 /** 067 * Get the {@code target} directory. 068 * @return {@link File} 069 */ 070 public File getTarget() { 071 if (isReference()) { 072 return getRef().getTarget(); 073 } 074 return target; 075 } 076 077 /** 078 * Set the {@code target} directory. 079 * @param target {@link File} 080 */ 081 public void setTarget(final File target) { 082 if (isReference()) { 083 throw tooManyAttributes(); 084 } 085 this.target = target; 086 } 087 088 /** 089 * Get the {@code classpathref}. 090 * @return {@link String} 091 */ 092 public String getClasspathref() { 093 if (isReference()) { 094 return getRef().getClasspathref(); 095 } 096 return classpathref; 097 } 098 099 /** 100 * Set the {@code classpathref}. 101 * @param classpathref {@link String} 102 */ 103 public void setClasspathRef(final String classpathref) { 104 if (isReference()) { 105 throw tooManyAttributes(); 106 } 107 this.classpathref = classpathref; 108 } 109 110 /** 111 * Return the effective classpath as a {@link List} of {@link String} 112 * filesystem paths. If {@link #includeSystemClasspath}, system classpath will be appended. 113 * @return List<String> 114 */ 115 public List<String> getClasspathEntries() { 116 final Path path = new Path(getProject()); 117 final Path classpath = getClasspath(); 118 if (classpath != null) { 119 path.add(classpath); 120 } 121 if (includeSystemClasspath) { 122 path.add(Path.systemClasspath); 123 } 124 125 return Arrays.asList(path.list()); 126 } 127 128 /** 129 * Get the {@code classpath}. 130 * @return {@link Path} 131 */ 132 public Path getClasspath() { 133 if (isReference()) { 134 return getRef().getClasspath(); 135 } 136 if (classpath == null) { 137 if (getClasspathref() != null) { 138 final Path ref = new Path(getProject()); 139 ref.setRefid(new Reference(getProject(), getClasspathref())); 140 return ref; 141 } 142 } else if (StringUtils.isNotBlank(getClasspathref())) { 143 throw new BuildException("Only one of classpathref|classpath is permitted."); 144 } 145 return classpath; 146 } 147 148 /** 149 * Set the {@code classpath}. 150 * @param classpath {@link Path} 151 */ 152 public void setClasspath(final Path classpath) { 153 if (isReference()) { 154 throw tooManyAttributes(); 155 } 156 if (this.classpath != null) { 157 throw new BuildException("classpath already set"); 158 } 159 this.classpath = classpath; 160 } 161 162 /** 163 * Create the nested {@code properties}. 164 * @return {@link InlineProperties} 165 */ 166 public InlineProperties createProperties() { 167 if (isReference()) { 168 throw noChildrenAllowed(); 169 } 170 if (inlineProperties != null) { 171 throw new BuildException("properties already specified"); 172 } 173 inlineProperties = new InlineProperties(); 174 return inlineProperties; 175 } 176 177 /** 178 * Create a nested {@code propertyset}. 179 * @return {@link PropertySet} 180 */ 181 public PropertySet createPropertySet() { 182 if (isReference()) { 183 throw noChildrenAllowed(); 184 } 185 if (propertySet != null) { 186 throw new BuildException("propertyset already specified"); 187 } 188 propertySet = new PropertySet(); 189 propertySet.setProject(getProject()); 190 return propertySet; 191 } 192 193 /** 194 * Set whether to include the system classpath. 195 * @param includeSystemClasspath the includeSystemClasspath to set 196 * @since 1.3 197 * @see Path#systemClasspath 198 */ 199 public void setIncludeSystemClasspath(final boolean includeSystemClasspath) { 200 this.includeSystemClasspath = includeSystemClasspath; 201 } 202 203 /** 204 * Merge nested {@code propertyset} and {@code properties}; latter takes precedence. 205 * @return Properties 206 */ 207 public Properties getProperties() { 208 if (isReference()) { 209 return getRef().getProperties(); 210 } 211 if (propertySet == null && inlineProperties == null) { 212 createPropertySet().appendBuiltin( 213 (BuiltinPropertySetName) EnumeratedAttribute.getInstance(BuiltinPropertySetName.class, "all")); 214 } 215 final Properties result = new Properties(); 216 if (propertySet != null) { 217 result.putAll(propertySet.getProperties()); 218 } 219 if (inlineProperties != null) { 220 for (final Map.Entry<Object, Object> entry : inlineProperties.properties.entrySet()) { 221 result.put(entry.getKey(), StringUtils.trim((String) entry.getValue())); 222 } 223 } 224 return result; 225 } 226 227 private WeaverSettings getRef() { 228 return getCheckedRef(WeaverSettings.class, "settings"); 229 } 230 231}