001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.vfs2.provider.compressed;
018
019import org.apache.commons.vfs2.Capability;
020import org.apache.commons.vfs2.FileObject;
021import org.apache.commons.vfs2.FileSystemException;
022import org.apache.commons.vfs2.FileType;
023import org.apache.commons.vfs2.provider.AbstractFileName;
024import org.apache.commons.vfs2.provider.AbstractFileObject;
025
026/**
027 * A compressed file.
028 *
029 * <p>
030 * Such a file only has one child (the compressed file name with stripped last extension)
031 * </p>
032 *
033 * @param <FS> A CompressedFileFileSystem
034 */
035public abstract class CompressedFileFileObject<FS extends CompressedFileFileSystem> extends AbstractFileObject<FS> {
036
037    /**
038     * The value returned by {@link #doGetContentSize()} when not overridden by a subclass.
039     *
040     * @since 2.5.0
041     */
042    public static final int SIZE_UNDEFINED = -1;
043    private final FileObject container;
044    private final String[] children;
045
046    /**
047     * Constructs a new instance.
048     *
049     * @param fileName the file name.
050     * @param container the container.
051     * @param fileSystem the file system.
052     */
053    protected CompressedFileFileObject(final AbstractFileName fileName, final FileObject container, final FS fileSystem) {
054        super(fileName, fileSystem);
055        this.container = container;
056
057        // TODO, add getBaseName(String) to FileName
058        String baseName = container.getName().getBaseName();
059        final int pos = baseName.lastIndexOf('.');
060        if (pos > 0) {
061            baseName = baseName.substring(0, pos);
062        }
063        children = new String[] {baseName};
064    }
065
066    @Override
067    public void createFile() throws FileSystemException {
068        container.createFile();
069        injectType(FileType.FILE);
070    }
071
072    /**
073     * Returns the size of the file content (in bytes). Is only called if {@link #doGetType} returns
074     * {@link FileType#FILE}.
075     */
076    @Override
077    protected long doGetContentSize() {
078        return SIZE_UNDEFINED;
079    }
080
081    /**
082     * Returns the last modified time of this file.
083     */
084    @Override
085    protected long doGetLastModifiedTime() throws Exception {
086        return container.getContent().getLastModifiedTime();
087    }
088
089    /**
090     * Returns the file's type.
091     */
092    @Override
093    protected FileType doGetType() throws FileSystemException {
094        if (getName().getPath().endsWith("/")) {
095            return FileType.FOLDER;
096        }
097        return FileType.FILE;
098    }
099
100    /**
101     * Lists the children of the file.
102     */
103    @Override
104    protected String[] doListChildren() {
105        return children;
106    }
107
108    /**
109     * Gets the container.
110     *
111     * @return the container.
112     */
113    protected FileObject getContainer() {
114        return container;
115    }
116
117    /**
118     * Determines if this file can be written to.
119     *
120     * @return {@code true} if this file is writable, {@code false} if not.
121     * @throws FileSystemException if an error occurs.
122     */
123    @Override
124    public boolean isWriteable() throws FileSystemException {
125        return getFileSystem().hasCapability(Capability.WRITE_CONTENT);
126    }
127}