001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2010–2011 ApexIdentity Inc.
015 * Portions Copyright 2011-2014 ForgeRock AS.
016 */
017
018package org.forgerock.openig.io;
019
020import java.io.File;
021
022import org.forgerock.openig.heap.GenericHeaplet;
023import org.forgerock.openig.heap.HeapException;
024import org.forgerock.util.Factory;
025
026
027/**
028 * Allocates temporary buffers for caching streamed content during request processing.
029 */
030public class TemporaryStorage implements Factory<Buffer> {
031
032    /**
033     * Key to retrieve a {@link TemporaryStorage} instance from the {@link org.forgerock.openig.heap.Heap}.
034     */
035    public static final String TEMPORARY_STORAGE_HEAP_KEY = "TemporaryStorage";
036
037    /**
038     * 8 KiB.
039     */
040    public static final int HEIGHT_KB = 8 * 1024;
041
042    /**
043     * 64 KiB.
044     */
045    public static final int SIXTY_FOUR_KB = 64 * 1024;
046
047    /**
048     * 1 MiB.
049     */
050    public static final int ONE_MB = 1 * 1024 * 1024;
051
052    /**
053     * The initial length of memory buffer byte array. Default: 8 KiB.
054     */
055    private final int initialLength;
056
057    /**
058     * The length limit of the memory buffer. Attempts to exceed this limit will result in
059     * promoting the buffer from a memory to a file buffer. Default: 64 KiB.
060     */
061    private final int memoryLimit;
062
063    /**
064     * The length limit of the file buffer. Attempts to exceed this limit will result in an
065     * {@link OverflowException} being thrown. Default: 1 MiB.
066     */
067    private final int fileLimit;
068
069    /**
070     * The directory where temporary files are created. If {@code null}, then the
071     * system-dependent default temporary directory will be used. Default: {@code null}.
072     *
073     * @see java.io.File#createTempFile(String, String, File)
074     */
075    private final File directory;
076
077    /**
078     * Builds a storage using the system dependent default temporary directory and default sizes.
079     * Equivalent to call {@code new TemporaryStorage(null)}.
080     * @see #TemporaryStorage(File)
081     */
082    public TemporaryStorage() {
083        this(null);
084    }
085
086    /**
087     * Builds a storage using the given directory (may be {@literal null}) and default sizes. Equivalent to call {@code
088     * new TemporaryStorage(directory, HEIGHT_KB, SIXTY_FOUR_KB, ONE_MB)}.
089     *
090     * @param directory
091     *         The directory where temporary files are created. If {@code null}, then the system-dependent default
092     *         temporary directory will be used.
093     * @see #TemporaryStorage(File, int, int, int)
094     */
095    public TemporaryStorage(final File directory) {
096        this(directory, HEIGHT_KB, SIXTY_FOUR_KB, ONE_MB);
097    }
098
099    /**
100     * Builds a storage using the given directory (may be {@literal null}) and provided sizes.
101     *
102     * @param directory
103     *         The directory where temporary files are created. If {@code null}, then the system-dependent default
104     *         temporary directory will be used.
105     * @param initialLength
106     *         The initial length of memory buffer byte array.
107     * @param memoryLimit
108     *         The length limit of the memory buffer. Attempts to exceed this limit will result in promoting the buffer
109     *         from a memory to a file buffer.
110     * @param fileLimit
111     *         The length limit of the file buffer. Attempts to exceed this limit will result in an {@link
112     *         OverflowException} being thrown.
113     * @see #TemporaryStorage(File, int, int, int)
114     */
115    public TemporaryStorage(final File directory,
116                            final int initialLength,
117                            final int memoryLimit,
118                            final int fileLimit) {
119        this.initialLength = initialLength;
120        this.memoryLimit = memoryLimit;
121        this.fileLimit = fileLimit;
122        this.directory = directory;
123    }
124
125    /**
126     * Creates and returns a new instance of a temporary buffer.
127     *
128     * @return a new instance of a temporary buffer.
129     */
130    public Buffer newInstance() {
131        return new TemporaryBuffer(initialLength, memoryLimit, fileLimit, directory);
132    }
133
134    /**
135     * Creates and initializes a temporary storage object in a heap environment.
136     */
137    public static class Heaplet extends GenericHeaplet {
138        @Override
139        public Object create() throws HeapException {
140            return new TemporaryStorage(config.get("directory").asFile(),
141                                        config.get("initialLength").defaultTo(HEIGHT_KB).asInteger(),
142                                        config.get("memoryLimit").defaultTo(SIXTY_FOUR_KB).asInteger(),
143                                        config.get("fileLimit").defaultTo(ONE_MB).asInteger());
144        }
145    }
146}