View Javadoc
1   package org.apache.maven.shared.utils.io;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import javax.annotation.Nonnull;
23  import java.io.File;
24  import java.io.IOException;
25  import java.lang.reflect.Array;
26  import java.lang.reflect.InvocationTargetException;
27  import java.lang.reflect.Method;
28  
29  /**
30   * Java7 feature detection
31   *
32   * @author Kristian Rosenvold
33   */
34  public class Java7Support
35  {
36  
37      private static final boolean IS_JAVA7;
38  
39      private static Method isSymbolicLink;
40  
41      private static Method delete;
42  
43      private static Method toPath;
44  
45      private static Method exists;
46  
47      private static Method toFile;
48  
49      private static Method readSymlink;
50  
51      private static Method createSymlink;
52  
53      private static Object emptyLinkOpts;
54  
55      private static Object emptyFileAttributes;
56  
57      static
58      {
59          boolean isJava7x = true;
60          try
61          {
62              Class<?> files = Thread.currentThread().getContextClassLoader().loadClass( "java.nio.file.Files" );
63              Class<?> path = Thread.currentThread().getContextClassLoader().loadClass( "java.nio.file.Path" );
64              Class<?> fa = Thread.currentThread().getContextClassLoader().loadClass( "java.nio.file.attribute.FileAttribute" );
65              Class<?> linkOption = Thread.currentThread().getContextClassLoader().loadClass( "java.nio.file.LinkOption" );
66              isSymbolicLink = files.getMethod( "isSymbolicLink", path );
67              delete = files.getMethod( "delete", path );
68              readSymlink = files.getMethod( "readSymbolicLink", path );
69  
70              emptyFileAttributes = Array.newInstance( fa, 0 );
71              final Object o = emptyFileAttributes;
72              createSymlink  = files.getMethod( "createSymbolicLink", path,path, o.getClass() );
73              emptyLinkOpts = Array.newInstance( linkOption, 0 );
74              exists = files.getMethod( "exists", path, emptyLinkOpts.getClass() );
75              toPath = File.class.getMethod( "toPath" );
76              toFile = path.getMethod( "toFile" );
77          }
78          catch ( ClassNotFoundException e )
79          {
80              isJava7x = false;
81          }
82          catch ( NoSuchMethodException e )
83          {
84              isJava7x = false;
85          }
86          IS_JAVA7 = isJava7x;
87      }
88  
89      public static boolean isSymLink( @Nonnull File file )
90      {
91          try
92          {
93              Object path = toPath.invoke( file );
94              return (Boolean) isSymbolicLink.invoke( null, path );
95          }
96          catch ( IllegalAccessException e )
97          {
98              throw new RuntimeException( e );
99          }
100         catch ( InvocationTargetException e )
101         {
102             throw new RuntimeException( e );
103         }
104     }
105 
106 
107     public static @Nonnull File readSymbolicLink( @Nonnull File symlink )
108         throws IOException
109     {
110         try
111         {
112             Object path = toPath.invoke( symlink );
113             Object resultPath =  readSymlink.invoke( null, path );
114             return (File) toFile.invoke( resultPath );
115         }
116         catch ( IllegalAccessException e )
117         {
118             throw new RuntimeException( e );
119         }
120         catch ( InvocationTargetException e )
121         {
122             throw new RuntimeException( e );
123         }
124     }
125 
126 
127     public static boolean exists( @Nonnull File file )
128         throws IOException
129     {
130         try
131         {
132             Object path = toPath.invoke( file );
133             final Object invoke = exists.invoke( null, path, emptyLinkOpts );
134             return (Boolean) invoke;
135         }
136         catch ( IllegalAccessException e )
137         {
138             throw new RuntimeException( e );
139         }
140         catch ( InvocationTargetException e )
141         {
142             throw (RuntimeException) e.getTargetException();
143         }
144 
145     }
146 
147     public static @Nonnull File createSymbolicLink( @Nonnull File symlink,  @Nonnull File target )
148         throws IOException
149     {
150         try
151         {
152             if (!exists( symlink )){
153                 Object link = toPath.invoke( symlink );
154                 Object path = createSymlink.invoke( null, link, toPath.invoke( target ), emptyFileAttributes );
155                 return (File) toFile.invoke( path );
156             }
157             return symlink;
158         }
159         catch ( IllegalAccessException e )
160         {
161             throw new RuntimeException( e );
162         }
163         catch ( InvocationTargetException e )
164         {
165             final Throwable targetException = e.getTargetException();
166             throw (IOException)targetException;
167         }
168 
169     }
170     /**
171      * Performs a nio delete
172      * @param file the file to delete
173      * @throws IOException
174      */
175 
176     public static void delete( File file ) throws IOException
177     {
178         try
179         {
180             Object path = toPath.invoke( file );
181             delete.invoke( null, path );
182         }
183         catch ( IllegalAccessException e )
184         {
185             throw new RuntimeException( e );
186         }
187         catch ( InvocationTargetException e )
188         {
189             throw (IOException) e.getTargetException();
190         }
191     }
192 
193     public static boolean isJava7()
194     {
195         return IS_JAVA7;
196     }
197 
198     public static boolean isAtLeastJava7()
199     {
200         return IS_JAVA7;
201     }
202 
203 }