rascal.object.AbstractObjectFactory.java Source code

Java tutorial

Introduction

Here is the source code for rascal.object.AbstractObjectFactory.java

Source

/*
 * Copyright 2009, Andrej Viepra
 *
 * 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 rascal.object;

import org.apache.commons.lang.ArrayUtils;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;

public abstract class AbstractObjectFactory implements ObjectFactory {
    private static final int OBJECT_HEADER_BUFFER_LENGTH = 32;

    protected abstract ReadableByteChannel getChannel(String objectName) throws IOException;

    private GitObjectType parseObjectType(byte[] buffer) throws UnknownObjectTypeException {
        String typeName = new String(buffer);
        if (GitObjectType.BLOB.toString().equals(typeName)) {
            return GitObjectType.BLOB;
        } else if (GitObjectType.TREE.toString().equals(typeName)) {
            return GitObjectType.TREE;
        } else if (GitObjectType.COMMIT.toString().equals(typeName)) {
            return GitObjectType.COMMIT;
        } else if (GitObjectType.TAG.toString().equals(typeName)) {
            return GitObjectType.TAG;
        }
        throw new UnknownObjectTypeException(typeName);
    }

    private long parseObjectSize(byte[] buffer) throws NumberFormatException {
        String sizeString = new String(buffer);
        return Long.valueOf(sizeString);
    }

    private GitObject createObject(final String name, byte[] buffer, int headerSpaceIndex, int headerEndIndex)
            throws CorruptedObjectException, UnknownObjectTypeException, NumberFormatException {
        GitObjectType type = parseObjectType(ArrayUtils.subarray(buffer, 0, headerSpaceIndex));
        long size = parseObjectSize(ArrayUtils.subarray(buffer, headerSpaceIndex + 1, headerEndIndex));
        if (size <= 0) {
            throw new CorruptedObjectException(name, "Wrong object size");
        }
        return new GitObject(name, type, size) {
            public ReadableByteChannel getContentChannel() throws IOException {
                return AbstractObjectFactory.this.getChannel(name);
            }
        };
    }

    public GitObject createObject(String name) throws IOException, CorruptedObjectException {
        ReadableByteChannel channel = getChannel(name);
        byte[] buffer = new byte[OBJECT_HEADER_BUFFER_LENGTH];
        channel.read(ByteBuffer.wrap(buffer));
        channel.close();
        int headerSpaceIndex;
        int headerEndIndex;
        if ((headerSpaceIndex = ArrayUtils.indexOf(buffer, (byte) ' ')) == ArrayUtils.INDEX_NOT_FOUND
                || (headerEndIndex = ArrayUtils.indexOf(buffer, (byte) 0)) == ArrayUtils.INDEX_NOT_FOUND
                || headerSpaceIndex >= headerEndIndex) {
            throw new CorruptedObjectException(name, "Corrupted object header");
        }
        try {
            return createObject(name, buffer, headerSpaceIndex, headerEndIndex);
        } catch (UnknownObjectTypeException e) {
            throw new CorruptedObjectException(name, e);
        } catch (NumberFormatException e) {
            throw new CorruptedObjectException(name, e);
        }
    }
}