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.wicket.settings;
018
019import java.io.File;
020import java.io.IOException;
021import java.util.function.Supplier;
022
023import org.apache.wicket.Application;
024import org.apache.wicket.WicketRuntimeException;
025import org.apache.wicket.pageStore.crypt.DefaultCrypter;
026import org.apache.wicket.pageStore.crypt.ICrypter;
027import org.apache.wicket.protocol.http.WebApplication;
028import org.apache.wicket.util.lang.Args;
029import org.apache.wicket.util.lang.Bytes;
030
031/**
032 * A class for settings related to the the storages where page instances are persisted, used by
033 * {@link org.apache.wicket.pageStore.IPageStore} {@link org.apache.wicket.page.IPageManager}.
034 * <p>
035 * For more information about page storages read <a
036 * href="https://cwiki.apache.org/confluence/x/qIaoAQ">Page Storage - Wiki page</a>
037 * </p>
038 *
039 * @since 1.5
040 */
041public class StoreSettings
042{
043        private static final Bytes DEFAULT_MAX_SIZE_PER_SESSION = Bytes.megabytes(10);
044
045        private static final int DEFAULT_ASYNCHRONOUS_QUEUE_CAPACITY = 100;
046
047        private Bytes maxSizePerSession = DEFAULT_MAX_SIZE_PER_SESSION;
048
049        private File fileStoreFolder = null;
050
051        private int asynchronousQueueCapacity = DEFAULT_ASYNCHRONOUS_QUEUE_CAPACITY;
052
053        private boolean asynchronous = true;
054        
055        private boolean encrypted = false;
056        
057        private Supplier<ICrypter> crypter = DefaultCrypter::new;
058
059        /**
060         * Construct.
061         * 
062         * @param application
063         */
064        public StoreSettings(final Application application)
065        {
066        }
067
068        /**
069         * @return maximum page size. After this size is exceeded,
070         * the {@link org.apache.wicket.pageStore.DiskPageStore} will start saving the
071         * pages at the beginning of file.
072         */
073        public Bytes getMaxSizePerSession()
074        {
075                return maxSizePerSession;
076        }
077
078        /**
079         * Sets the maximum size of the {@link File} where page instances per session are stored. After
080         * reaching this size the {@link org.apache.wicket.pageStore.DiskPageStore} will start overriding the
081         * oldest pages at the beginning of the file.
082         *
083         * @param maxSizePerSession
084         *            the maximum size of the file where page instances are stored per session. In
085         *            bytes.
086         * @return {@code this} object for chaining
087         */
088        public StoreSettings setMaxSizePerSession(final Bytes maxSizePerSession)
089        {
090                this.maxSizePerSession = Args.notNull(maxSizePerSession, "maxSizePerSession");
091                return this;
092        }
093
094        /**
095         * @return the location of the folder where {@link org.apache.wicket.pageStore.DiskPageStore} will store the files with page
096         *         instances per session
097         */
098        public File getFileStoreFolder()
099        {
100                if (fileStoreFolder == null)
101                {
102                        if (WebApplication.exists())
103                        {
104                                fileStoreFolder = (File) WebApplication.get().getServletContext()
105                                        .getAttribute("jakarta.servlet.context.tempdir");
106                        }
107
108                        if (fileStoreFolder != null)
109                        {
110                                return fileStoreFolder;
111                        }
112
113                        try
114                        {
115                                fileStoreFolder = File.createTempFile("file-prefix", null).getParentFile();
116                        }
117                        catch (IOException e)
118                        {
119                                throw new WicketRuntimeException(e);
120                        }
121                }
122                return fileStoreFolder;
123        }
124
125        /**
126         * Sets the folder where {@link org.apache.wicket.pageStore.DiskPageStore} will store the files with page instances per
127         * session
128         *
129         * @param fileStoreFolder
130         *            the new location
131         * @return {@code this} object for chaining
132         */
133        public StoreSettings setFileStoreFolder(final File fileStoreFolder)
134        {
135                this.fileStoreFolder = Args.notNull(fileStoreFolder, "fileStoreFolder");
136                return this;
137        }
138
139        /**
140         * @return the capacity of the queue used to store the pages which will be stored asynchronously
141         * @see org.apache.wicket.pageStore.AsynchronousPageStore
142         */
143        public int getAsynchronousQueueCapacity()
144        {
145                return asynchronousQueueCapacity;
146        }
147
148        /**
149         * Sets the capacity of the queue used to store the pages which will be stored asynchronously
150         *
151         * @param queueCapacity
152         *            the capacity of the queue
153         * @see org.apache.wicket.pageStore.AsynchronousPageStore
154         * @return {@code this} object for chaining
155         */
156        public StoreSettings setAsynchronousQueueCapacity(int queueCapacity)
157        {
158                if (queueCapacity < 1)
159                {
160                        throw new IllegalArgumentException(
161                                "The capacity of the asynchronous queue should be at least 1.");
162                }
163                asynchronousQueueCapacity = queueCapacity;
164                return this;
165        }
166
167        /**
168         * Sets a flag whether to wrap the configured {@link org.apache.wicket.pageStore.IPageStore} with
169         * {@link org.apache.wicket.pageStore.AsynchronousPageStore}. By doing this the HTTP worker thread will not wait for the
170         * actual write of the page's bytes into the wrapped {@link org.apache.wicket.pageStore.IPageStore}.
171         *
172         * @param async
173         *            {@code true} to make it asynchronous, {@code false} - otherwise
174         * @return {@code this} object for chaining
175         */
176        public StoreSettings setAsynchronous(boolean async)
177        {
178                asynchronous = async;
179                return this;
180        }
181
182        /**
183         * @return {@code true} if the storing of page is asynchronous
184         */
185        public boolean isAsynchronous()
186        {
187                return asynchronous;
188        }
189        
190        /**
191         * Sets a flag whether to wrap the configured {@link org.apache.wicket.pageStore.IPageStore} with
192         * {@link org.apache.wicket.pageStore.CryptingPageStore}.
193         *
194         * @param encrypted
195         *            {@code true} to encrypt, {@code false} - otherwise
196         * @return {@code this} object for chaining
197         */
198        public StoreSettings setEncrypted(boolean encrypted)
199        {
200                this.encrypted = encrypted;
201                return this;
202        }
203        
204        /**
205         * @return {@code true} if the storing of page is encrypted
206         */
207        public boolean isEncrypted()
208        {
209                return encrypted;
210        }
211        
212        /**
213         * Sets the supplier for the {@link ICrypter} used by a
214         * {@link org.apache.wicket.pageStore.CryptingPageStore}.
215         * 
216         * @param crypter
217         *            The new supplier for an {@link ICrypter}.
218         * @return {@code this} object for chaining
219         */
220        public StoreSettings setCrypter(Supplier<ICrypter> crypter)
221        {
222                this.crypter = crypter;
223                return this;
224        }
225
226        /**
227         * @return the supplier used to create a {@link ICrypter} for a
228         *         {@link org.apache.wicket.pageStore.CryptingPageStore}. The default is
229         *         {@link DefaultCrypter}.
230         */
231        public Supplier<ICrypter> getCrypter()
232        {
233                return crypter;
234        }
235}