package org.jtheque.collections.impl; /* * Copyright JTheque (Baptiste Wicht) * * 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. */ import org.jtheque.collections.CollectionListener; import org.jtheque.collections.DaoCollections; import org.jtheque.collections.DataCollection; import org.jtheque.collections.CollectionsService; import org.jtheque.core.Core; import org.jtheque.file.FileService; import org.jtheque.persistence.DataListener; import org.jtheque.schemas.Schema; import org.jtheque.schemas.SchemaService; import org.jtheque.utils.CryptoUtils; import org.jtheque.utils.Hasher; import org.jtheque.utils.SimplePropertiesCache; import org.jtheque.utils.StringUtils; import org.jtheque.utils.annotations.GuardedBy; import org.jtheque.utils.annotations.GuardedInternally; import org.jtheque.utils.annotations.ThreadSafe; import org.jtheque.utils.bean.Response; import org.jtheque.utils.collections.WeakEventListenerList; import org.springframework.transaction.annotation.Transactional; import java.util.Collection; /** * The implementation of the collections service. * * @author Baptiste Wicht */ @ThreadSafe public final class CollectionsServiceImpl implements CollectionsService { @GuardedInternally private final DaoCollections daoCollections; @GuardedInternally private final Core core; @GuardedInternally private final WeakEventListenerList<CollectionListener> listeners = WeakEventListenerList.create(); @GuardedBy("this") private boolean collectionChosen; /** * Construct a new CollectionsServiceImpl. * * @param daoCollections The dao collections. * @param fileService The file service. * @param core The core. * @param schemaService The schema service. * @param schema The schema of the collections. */ public CollectionsServiceImpl(DaoCollections daoCollections, FileService fileService, Core core, SchemaService schemaService, Schema schema) { super(); this.daoCollections = daoCollections; this.core = core; fileService.registerBackuper("jtheque-collections", new CollectionsBackuper(daoCollections)); schemaService.registerSchema("", schema); SimplePropertiesCache.put("collectionChosen", false); } @Override public Response chooseCollection(String collection, String password, boolean create) { synchronized (this) { if (collectionChosen) { return new Response(false); } if (create) { if (daoCollections.exists(collection)) { return new Response(false, "error.module.collection.exists"); } else { createCollection(collection, password); daoCollections.setCurrentCollection(daoCollections.getCollection(collection)); core.getConfiguration().setLastCollection(collection); } } else if (!login(collection, password)) { return new Response(false, "error.module.collection"); } SimplePropertiesCache.put("collectionChosen", true); fireCollectionChosen(); collectionChosen = true; return new Response(true); } } /** * Login using the specified collection and password. * * @param title The collection title. * @param password The password. * * @return <code>true</code> if the login is correct else <code>false</code>. */ private boolean login(String title, String password) { if (isLoginIncorrect(title, password)) { return false; } daoCollections.setCurrentCollection(daoCollections.getCollection(title)); core.getConfiguration().setLastCollection(title); return true; } /** * Indicate if a login is correct or not * * @param title The title of the collection. * @param password The password to login to the collection. * * @return true if the login is correct else false. */ private boolean isLoginIncorrect(String title, String password) { DataCollection collection = daoCollections.getCollection(title); if (collection == null) { return true; } if (collection.isProtection()) { String encrypted = CryptoUtils.hashMessage(password, Hasher.SHA256); if (!encrypted.equals(collection.getPassword())) { return true; } } return false; } /** * Fire a collection chosen event. */ private void fireCollectionChosen() { for (CollectionListener listener : listeners) { listener.collectionChosen(); } } @Override public void addCollectionListener(CollectionListener listener) { listeners.add(listener); } @Override public void removeCollectionListener(CollectionListener listener) { listeners.remove(listener); } /** * Create a collection. * * @param title The title of the collection. * @param password The password of the collection. */ @Transactional private void createCollection(String title, String password) { DataCollection collection = daoCollections.create(); collection.setTitle(title); if (StringUtils.isEmpty(password)) { collection.setProtection(false); collection.setPassword(""); } else { collection.setProtection(true); collection.setPassword(CryptoUtils.hashMessage(password, Hasher.SHA256)); } daoCollections.save(collection); } @Override public Collection<DataCollection> getDatas() { return daoCollections.getCollections(); } @Override public void addDataListener(DataListener listener) { daoCollections.addDataListener(listener); } @Override @Transactional public void clearAll() { daoCollections.clearAll(); } @Override public String getDataType() { return DATA_TYPE; } }