Java tutorial
/** * Copyright 2013 - 2017 WaveMaker, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.wavemaker.commons.io.store; import java.util.Collections; import java.util.Iterator; import java.util.NoSuchElementException; import org.springframework.util.Assert; import com.wavemaker.commons.io.AbstractResources; import com.wavemaker.commons.io.File; import com.wavemaker.commons.io.Folder; import com.wavemaker.commons.io.JailedResourcePath; import com.wavemaker.commons.io.Resource; import com.wavemaker.commons.io.ResourcePath; import com.wavemaker.commons.io.ResourceStringFormat; import com.wavemaker.commons.io.Resources; import com.wavemaker.commons.io.ResourcesCollection; import com.wavemaker.commons.io.exception.ResourceDoesNotExistException; import com.wavemaker.commons.io.exception.ResourceExistsException; /** * A {@link Folder} that is backed by a {@link FolderStore}. Allows developers to use the simpler {@link FolderStore} * interface to provide a full {@link Folder} implementation. Subclasses must provide a suitable {@link FolderStore} * implementation via the {@link #getStore()} method. * * @see FolderStore * @see StoredFile * * @author Phillip Webb */ public abstract class StoredFolder extends StoredResource implements Folder { @Override protected abstract FolderStore getStore(); @Override public Resource getExisting(String name) throws ResourceDoesNotExistException { Assert.hasLength(name, "Name must not be empty"); JailedResourcePath resourcePath = getPath().get(name); Resource resource = getStore().getExisting(resourcePath); if (resource == null) { throw new ResourceDoesNotExistException(this, name); } return resource; } @Override public boolean hasExisting(String name) { Assert.hasLength(name, "Name must not be empty"); JailedResourcePath resourcePath = getPath().get(name); Resource existing = getStore().getExisting(resourcePath); return existing != null; } @Override public Folder getFolder(String name) { Assert.hasLength(name, "Name must not be empty"); JailedResourcePath folderPath = getPath().get(name); return getStore().getFolder(folderPath); } @Override public File getFile(String name) { Assert.hasLength(name, "Name must not be empty"); JailedResourcePath filePath = getPath().get(name); return getStore().getFile(filePath); } @SuppressWarnings("unchecked") @Override public <T extends Resource> T get(String name, Class<T> resourceType) { Assert.hasLength(name, "Name must not be empty"); Assert.notNull(resourceType, "ResourceType must not be null"); if (resourceType.equals(Folder.class)) { return (T) getFolder(name); } if (resourceType.equals(File.class)) { return (T) getFile(name); } return (T) getExisting(name); } @Override public Iterator<Resource> iterator() { return list().iterator(); } @Override public Resources<Resource> list() { if (!exists()) { return new ResourcesCollection<Resource>(this); } return new ChildResources(new Iterable<Resource>() { @Override public Iterator<Resource> iterator() { return new ChildResourceIterator(StoredFolder.this); } }); } @Override public Resources<Resource> find() { if (!exists()) { return new ResourcesCollection<Resource>(this); } return new ChildResources(new Iterable<Resource>() { @Override public Iterator<Resource> iterator() { return new RecursiveChildResourceIterator(StoredFolder.this); } }); } @Override public Folder copyTo(Folder folder) { Assert.notNull(folder, "Folder must not be empty"); ensureExists(); Assert.state(getPath().getParent() != null, "Unable to copy a root folder"); Folder destination = createDestinationFolder(folder); for (Resource child : list()) { child.copyTo(destination); } return destination; } @Override public Resources<Resource> copyContentsTo(Folder folder) { return list().copyTo(folder); } @Override public Folder moveTo(Folder folder) { Assert.notNull(folder, "Folder must not be empty"); ensureExists(); Assert.state(getPath().getParent() != null, "Unable to move a root folder"); Folder destination = createDestinationFolder(folder); for (Resource child : list()) { child.moveTo(destination); } return destination; } @Override public Resources<Resource> moveContentsTo(Folder folder) { return list().moveTo(folder); } private Folder createDestinationFolder(Folder folder) { Folder destination = folder.getFolder(getName()); destination.createIfMissing(); return destination; } @Override public Folder rename(String name) throws ResourceExistsException { return (Folder) super.rename(name); } @Override public void delete() { if (exists()) { for (Resource child : list()) { child.delete(); } getStore().delete(); } } @Override public void createIfMissing() { if (!exists()) { createParentIfMissing(); getStore().create(); } } @Override public Folder jail() { JailedResourcePath jailedPath = new JailedResourcePath(getPath().getUnjailedPath(), new ResourcePath()); return getStore().getFolder(jailedPath); } @Override public String toString(ResourceStringFormat format) { return super.toString(format) + "/"; } private static class ChildResourceIterator implements Iterator<Resource> { private final StoredFolder folder; private final Iterator<String> childNames; private Resource next; public ChildResourceIterator(StoredFolder folder) { this.folder = folder; Iterable<String> list = folder.getStore().list(); this.childNames = list == null ? Collections.<String>emptyList().iterator() : list.iterator(); } @Override public boolean hasNext() { ensureNextHasBeenFetched(); return this.next != null; } @Override public Resource next() { try { ensureNextHasBeenFetched(); if (this.next == null) { throw new NoSuchElementException(); } return this.next; } finally { this.next = null; } } private void ensureNextHasBeenFetched() { while (this.next == null && this.childNames.hasNext()) { String name = this.childNames.next(); JailedResourcePath path = this.folder.getStore().getPath().get(name); Resource resource = this.folder.getStore().getExisting(path); if (resource != null) { this.next = resource; } } } @Override public void remove() { throw new UnsupportedOperationException(); } } private class RecursiveChildResourceIterator implements Iterator<Resource> { private final Iterator<Resource> iterator; private Iterator<Resource> current; public RecursiveChildResourceIterator(StoredFolder folder) { this.iterator = new ChildResourceIterator(folder); } @Override public boolean hasNext() { return this.current != null && this.current.hasNext() || this.iterator.hasNext(); } @Override public Resource next() { if (this.current != null && this.current.hasNext()) { return this.current.next(); } this.current = null; Resource next = this.iterator.next(); if (next instanceof StoredFolder) { StoredFolder folder = (StoredFolder) next; this.current = new RecursiveChildResourceIterator(folder); } return next; } @Override public void remove() { throw new UnsupportedOperationException(); } } private class ChildResources extends AbstractResources<Resource> { private final Iterable<Resource> iterable; public ChildResources(Iterable<Resource> iterable) { Assert.notNull(iterable, "Iterable must not be null"); this.iterable = iterable; } @Override public Folder getSource() { return StoredFolder.this; } @Override public Iterator<Resource> iterator() { return this.iterable.iterator(); } } }