View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.vfs2.impl;
18  
19  import java.io.File;
20  import java.security.AccessController;
21  import java.security.PrivilegedAction;
22  import java.security.PrivilegedActionException;
23  import java.security.PrivilegedExceptionAction;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.vfs2.FileObject;
27  import org.apache.commons.vfs2.FileSelector;
28  import org.apache.commons.vfs2.FileSystemException;
29  import org.apache.commons.vfs2.provider.FileReplicator;
30  import org.apache.commons.vfs2.provider.VfsComponent;
31  import org.apache.commons.vfs2.provider.VfsComponentContext;
32  
33  /**
34   * A file replicator that wraps another file replicator, performing the replication as a privileged action.
35   */
36  public class PrivilegedFileReplicator implements FileReplicator, VfsComponent {
37  
38      /**
39       * An action that closes the wrapped replicator.
40       */
41      private final class CloseAction implements PrivilegedAction<Object> {
42          /**
43           * Performs the action.
44           */
45          @Override
46          public Object run() {
47              replicatorComponent.close();
48              return null;
49          }
50      }
51      /**
52       * An action that initializes the wrapped replicator.
53       */
54      private final class InitAction implements PrivilegedExceptionAction<Object> {
55          /**
56           * Performs the action.
57           */
58          @Override
59          public Object run() throws Exception {
60              replicatorComponent.init();
61              return null;
62          }
63      }
64  
65      /**
66       * An action that replicates a file using the wrapped replicator.
67       */
68      private final class ReplicateAction implements PrivilegedExceptionAction<File> {
69          private final FileObject srcFile;
70          private final FileSelector selector;
71  
72          ReplicateAction(final FileObject srcFile, final FileSelector selector) {
73              this.srcFile = srcFile;
74              this.selector = selector;
75          }
76  
77          /**
78           * Performs the action.
79           *
80           * @throws Exception if an error occurs.
81           */
82          @Override
83          public File run() throws Exception {
84              // TODO - Do not pass the selector through. It is untrusted
85              // TODO - Need to determine which files can be read
86              return replicator.replicateFile(srcFile, selector);
87          }
88      }
89  
90      private final FileReplicator replicator;
91  
92      private final VfsComponent replicatorComponent;
93  
94      /**
95       * Constructs a new instance.
96       *
97       * @param replicator The replicator.
98       */
99      public PrivilegedFileReplicator(final FileReplicator replicator) {
100         this.replicator = replicator;
101         if (replicator instanceof VfsComponent) {
102             replicatorComponent = (VfsComponent) replicator;
103         } else {
104             replicatorComponent = null;
105         }
106     }
107 
108     /**
109      * Closes the replicator.
110      */
111     @Override
112     public void close() {
113         if (replicatorComponent != null) {
114             AccessController.doPrivileged(new CloseAction());
115         }
116     }
117 
118     /**
119      * Initializes the component.
120      *
121      * @throws FileSystemException if an error occurs.
122      */
123     @Override
124     public void init() throws FileSystemException {
125         if (replicatorComponent != null) {
126             try {
127                 AccessController.doPrivileged(new InitAction());
128             } catch (final PrivilegedActionException e) {
129                 throw new FileSystemException("vfs.impl/init-replicator.error", e);
130             }
131         }
132     }
133 
134     /**
135      * Creates a local copy of the file, and all its descendants.
136      *
137      * @param srcFile The source FileObject.
138      * @param selector The file selector.
139      * @return The replicated file.
140      * @throws FileSystemException if an error occurs.
141      */
142     @Override
143     public File replicateFile(final FileObject srcFile, final FileSelector selector) throws FileSystemException {
144         try {
145             final ReplicateAction action = new ReplicateAction(srcFile, selector);
146             return AccessController.doPrivileged(action);
147         } catch (final PrivilegedActionException e) {
148             throw new FileSystemException("vfs.impl/replicate-file.error", e, srcFile.getName());
149         }
150     }
151 
152     /**
153      * Sets the context for the replicator.
154      *
155      * @param context The component context.
156      */
157     @Override
158     public void setContext(final VfsComponentContext context) {
159         if (replicatorComponent != null) {
160             replicatorComponent.setContext(context);
161         }
162     }
163 
164     /**
165      * Sets the Logger to use for the component.
166      *
167      * @param logger The logger.
168      */
169     @Override
170     public void setLogger(final Log logger) {
171         if (replicatorComponent != null) {
172             replicatorComponent.setLogger(logger);
173         }
174     }
175 }