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.provider; 18 19 import java.util.ArrayList; 20 import java.util.stream.Stream; 21 22 import org.apache.commons.vfs2.FileSystemException; 23 24 /** 25 * A {@link VfsComponent} that contains a set of subcomponents. 26 */ 27 public abstract class AbstractVfsContainer extends AbstractVfsComponent { 28 29 /** 30 * The components contained by this component. 31 */ 32 private final ArrayList<Object> components = new ArrayList<>(); // @GuardedBy("self") 33 34 /** 35 * Constructs a new instance for subclasses. 36 */ 37 public AbstractVfsContainer() { 38 // empty 39 } 40 41 /** 42 * Adds a subcomponent to this component. 43 * <p> 44 * If the sub-component implements {@link VfsComponent}, it is initialized. All sub-components are closed when this 45 * component is closed. 46 * </p> 47 * 48 * @param component the component to add. 49 * @throws FileSystemException if any error occurs. 50 */ 51 protected void addComponent(final Object component) throws FileSystemException { 52 synchronized (components) { 53 if (!components.contains(component)) { 54 // Initialize 55 if (component instanceof VfsComponent) { 56 final VfsComponent vfsComponent = (VfsComponent) component; 57 vfsComponent.setLogger(getLogger()); 58 vfsComponent.setContext(getContext()); 59 vfsComponent.init(); 60 } 61 // Keep track of component, to close it later 62 components.add(component); 63 } 64 } 65 } 66 67 /** 68 * Closes the subcomponents of this component. 69 */ 70 @Override 71 public void close() { 72 final Object[] toclose; 73 synchronized (components) { 74 toclose = components.toArray(); 75 components.clear(); 76 } 77 // Close all components 78 Stream.of(toclose).filter(VfsComponent.class::isInstance) 79 .forEach(component -> ((VfsComponent) component).close()); 80 } 81 82 /** 83 * Removes a subcomponent from this component. 84 * 85 * @param component the component to remove. 86 */ 87 protected void removeComponent(final Object component) { 88 synchronized (components) { 89 // multiple instances should not happen 90 components.remove(component); 91 } 92 } 93 }