/*
* Copyright 2009-2016 Tilmann Zaeschke. All rights reserved.
*
* This file is part of ZooDB.
*
* ZooDB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ZooDB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ZooDB. If not, see <http://www.gnu.org/licenses/>.
*
* See the README and COPYING files for further information.
*/
package org.zoodb.jdo.impl;
import java.util.Properties;
import javax.jdo.Constants;
import javax.jdo.JDOUserException;
import javax.jdo.PersistenceManagerFactory;
import org.zoodb.api.ZooConstants;
import org.zoodb.tools.ZooHelper;
/**
* This class simulates the JDO PersistenceManagerFactory
*
* @author Tilmann Zaeschke
*/
public abstract class AbstractPersistenceManagerFactory
implements PersistenceManagerFactory, Cloneable {
//See JDO 2.0 Chapter 11, p87
// /** <code>OPTION_CONNECTION_URL</code> =
// * "javax.jdo.option.ConnectionURL"*/
//public static final String OPTION_CONNECTION_URL =
// "javax.jdo.option.ConnectionURL";
// /** <code>OPTION_RETAIN_VALUES</code> =
// * "javax.jdo.option.RetainValues"*/
// public static final String OPTION_RETAIN_VALUES =
// "javax.jdo.option.RetainValues";
// public static final String OPTION_USERNAME =
// "javax.jdo.option.ConnectionUserName";
// public static final String OPTION_PASSWORD =
// "javax.jdo.option.ConnectionPassword";
private static final long serialVersionUID = 1L;
//standard properties
private boolean isOptimistic = false;
private boolean isRetainValues = false;
private boolean isDetachAllOnCommit = false;
//should be 'false' by default
private boolean isIgnoreCache = false;
private boolean isMultiThreaded = false;
private String userName = null;
private transient String password = null;
private String database = null;
private boolean nonTransactionalRead = false;
private boolean autoCreateSchema = true;
private boolean evictPrimitives = false;
private boolean failOnClosedQueries = false;
// private boolean allowNonStandardSCOs = false;
//Non-standard properties.
//private boolean _isReadOnly = false; //now in JDO 2.2
private String sessionName = null;
private String persistenceUnitName = null;
private int oidAllocation = 50;
private boolean isFrozen = false;
/**
* @param props
*/
public AbstractPersistenceManagerFactory(Properties props) {
/*
- "javax.jdo.option.Optimistic"
- "javax.jdo.option.RetainValues"
- "javax.jdo.option.RestoreValues"
- "javax.jdo.option.IgnoreCache"
- "javax.jdo.option.NontransactionalRead"
- "javax.jdo.option.NontransactionalWrite"
- "javax.jdo.option.Multithreaded"
- "javax.jdo.option.DetachAllOnCommit"
- "javax.jdo.option.CopyOnAttach"
- "javax.jdo.option.ConnectionUserName"
- "javax.jdo.option.ConnectionPassword"
- "javax.jdo.option.ConnectionURL"
- "javax.jdo.option.ConnectionDriverName"
- "javax.jdo.option.ConnectionFactoryName"
- "javax.jdo.option.ConnectionFactory2Name"
- "javax.jdo.option.Mapping"
- "javax.jdo.mapping.Catalog"
- "javax.jdo.mapping.Schema"
- "javax.jdo.option.TransactionType"
- "javax.jdo.option.ServerTimeZoneID"
- "javax.jdo.option.ReadOnly"
The following two properties are only used in the props, not in the overrides.
- "javax.jdo.option.Name"
- "javax.jdo.option.PersistenceUnitName"
The property "javax.jdo.PersistenceManagerFactoryClass"
*/
for (Object keyO: props.keySet()) {
String key = (String) keyO;
if (Constants.PROPERTY_OPTIMISTIC.equals(key)) {
isOptimistic = Boolean.parseBoolean(props.getProperty(key));
} else if (Constants.PROPERTY_RETAIN_VALUES.equals(key)) {
isRetainValues = Boolean.parseBoolean(props.getProperty(key));
} else if (Constants.PROPERTY_RESTORE_VALUES.equals(key)) {
System.out.println("STUB: Property not supported: " + key + "=" + props.get(key)); //TODO
} else if (Constants.PROPERTY_IGNORE_CACHE.equals(key)) {
isIgnoreCache = Boolean.parseBoolean(props.getProperty(key));
} else if (Constants.PROPERTY_NONTRANSACTIONAL_READ.equals(key)) {
nonTransactionalRead = Boolean.parseBoolean(props.getProperty(key));
} else if (Constants.PROPERTY_NONTRANSACTIONAL_WRITE.equals(key)) {
System.out.println("STUB: Property not supported: " + key + "=" + props.get(key)); //TODO
} else if (Constants.PROPERTY_MULTITHREADED.equals(key)) {
isMultiThreaded = Boolean.parseBoolean(props.getProperty(key));
} else if (Constants.PROPERTY_DETACH_ALL_ON_COMMIT.equals(key)) {
isDetachAllOnCommit = Boolean.parseBoolean(props.getProperty(key));
} else if (Constants.PROPERTY_COPY_ON_ATTACH.equals(key)) {
System.out.println("STUB: Property not supported: " + key + "=" + props.get(key)); //TODO
} else if (Constants.PROPERTY_CONNECTION_USER_NAME.equals(key)) {
userName = props.getProperty(key);
} else if (Constants.PROPERTY_CONNECTION_PASSWORD.equals(key)) {
password = props.getProperty(key);
} else if (Constants.PROPERTY_CONNECTION_URL.equals(key)) {
database = props.getProperty(key);
//This is necessary, because the database name may have been set via XML or
//manually via properties.
database = ZooHelper.getDataStoreManager().getDbPath(database);
} else if (Constants.PROPERTY_CONNECTION_DRIVER_NAME.equals(key)) {
System.out.println("STUB: Property not supported: " + key + "=" + props.get(key)); //TODO
} else if (Constants.PROPERTY_CONNECTION_FACTORY_NAME.equals(key)) {
System.out.println("STUB: Property not supported: " + key + "=" + props.get(key)); //TODO
} else if (Constants.PROPERTY_CONNECTION_FACTORY2_NAME.equals(key)) {
System.out.println("STUB: Property not supported: " + key + "=" + props.get(key)); //TODO
} else if (Constants.PROPERTY_MAPPING.equals(key)) {
System.out.println("STUB: Property not supported: " + key + "=" + props.get(key)); //TODO
} else if (Constants.PROPERTY_MAPPING_CATALOG.equals(key)) {
System.out.println("STUB: Property not supported: " + key + "=" + props.get(key)); //TODO
} else if (Constants.PROPERTY_MAPPING_SCHEMA.equals(key)) {
System.out.println("STUB: Property not supported: " + key + "=" + props.get(key)); //TODO
} else if ("javax.jdo.option.TransactionType".equals(key)) {
System.out.println("STUB: Property not supported: " + key + "=" + props.get(key)); //TODO
} else if (Constants.PROPERTY_SERVER_TIME_ZONE_ID.equals(key)) {
System.out.println("STUB: Property not supported: " + key + "=" + props.get(key)); //TODO
} else if (Constants.PROPERTY_READONLY.equals(key)) {
System.out.println("STUB: Property not supported: " + key + "=" + props.get(key)); //TODO
//The following two properties are only used in the props, not in the overrides.
} else if (Constants.PROPERTY_NAME.equals(key)) {
sessionName = props.getProperty(key);
} else if (Constants.PROPERTY_PERSISTENCE_UNIT_NAME.equals(key)) {
persistenceUnitName = props.getProperty(key);
// } else if ("options".equals(key)) {
// String opt = props.getProperty(key);
// if ("0".equals(opt)) {
//
// } else {
// throw new IllegalArgumentException("o=" + opt);
// }
} else if (Constants.PROPERTY_PERSISTENCE_MANAGER_FACTORY_CLASS.equals(key)) {
//ignore
// } else if (ZooConstants.PROPERTY_ALLOW_NON_STANDARD_SCOS.equals(key)) {
// allowNonStandardSCOs = Boolean.parseBoolean(props.getProperty(key));
} else if (ZooConstants.PROPERTY_AUTO_CREATE_SCHEMA.equals(key)) {
autoCreateSchema = Boolean.parseBoolean(props.getProperty(key));
} else if (ZooConstants.PROPERTY_EVICT_PRIMITIVES.equals(key)) {
evictPrimitives = Boolean.parseBoolean(props.getProperty(key));
} else if (ZooConstants.PROPERTY_FAIL_ON_CLOSED_QUERIES.equals(key)) {
failOnClosedQueries = Boolean.parseBoolean(props.getProperty(key));
} else {
//throw new IllegalArgumentException("Unknown key: " + key);
System.err.println("Property not recognised: " + key + "=" + props.getProperty(key));
}
}
}
/**
* Freezes the properties of this factory. Should be called from any method
* that creates a PersistenceManager.
*/
protected void setFrozen() {
isFrozen = true;
}
/**
* Throws a JDOUserException if this factories properties are frozen.
* Should be called from every set-method.
*/
protected void checkFrozen() {
if (isFrozen) {
//TODO is this the correct exception?
throw new JDOUserException("This factory can't be modified.");
}
}
/**
* @see PersistenceManagerFactory#getRetainValues()
*/
@Override
public boolean getRetainValues() {
return isRetainValues;
}
/**
* @see PersistenceManagerFactory#setRetainValues(boolean)
*/
@Override
public void setRetainValues(boolean flag) {
checkFrozen();
isRetainValues = flag;
}
@Override
public String getConnectionUserName() {
return userName;
}
protected String getConnectionPassword() {
return password;
}
@Override
public boolean getDetachAllOnCommit() {
return isDetachAllOnCommit;
}
@Override
public void setDetachAllOnCommit(boolean arg0) {
checkFrozen();
this.isDetachAllOnCommit = arg0;
}
@Override
public boolean getOptimistic() {
return isOptimistic;
}
@Override
public boolean getNontransactionalRead() {
return nonTransactionalRead;
}
@Override
public void setNontransactionalRead(boolean arg0) {
checkFrozen();
nonTransactionalRead = arg0;
}
@Override
public void setConnectionPassword(String password) {
checkFrozen();
this.password = password;
}
@Override
public void setConnectionUserName(String userName) {
checkFrozen();
this.userName = userName;
}
@Override
public void setOptimistic(boolean flag) {
checkFrozen();
this.isOptimistic = flag;
}
@Override
public String getConnectionURL() {
return database;
}
@Override
public void setConnectionURL(String url) {
checkFrozen();
this.database = url;
}
@Override
public String getPersistenceUnitName() {
return persistenceUnitName;
}
@Override
public void setPersistenceUnitName(String arg0) {
checkFrozen();
this.persistenceUnitName = arg0;
}
public String getSessionName() {
return sessionName;
}
public void setSessionName(String sessionName) {
checkFrozen();
this.sessionName = sessionName;
}
public int getOidAllocation() {
return oidAllocation;
}
public void setOidAllocation(int size) {
checkFrozen(); //is this check required?
this.oidAllocation = size;
}
@Override
public boolean getIgnoreCache() {
return isIgnoreCache;
}
@Override
public boolean getMultithreaded() {
return isMultiThreaded;
}
@Override
public void setIgnoreCache(boolean arg0) {
//TODO
this.isIgnoreCache = arg0;
if (!isIgnoreCache)
System.out.println("STUB: IgnoreCache = false not supported."); //TODO
}
@Override
public void setMultithreaded(boolean arg0) {
this.isMultiThreaded = arg0;
}
@Override
public Object clone() {
AbstractPersistenceManagerFactory obj;
try {
obj = (AbstractPersistenceManagerFactory) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
obj.isFrozen = false; //Allow modification of cloned object
obj.setConnectionPassword(getConnectionPassword());
obj.setConnectionURL(getConnectionURL());
obj.setConnectionUserName(getConnectionUserName());
obj.setOidAllocation(getOidAllocation());
obj.setOptimistic(getOptimistic());
obj.setReadOnly(getReadOnly());
obj.setRetainValues(getRetainValues());
obj.setSessionName(null); //Force creation of a new name
obj.setIgnoreCache(obj.getIgnoreCache());
obj.setDetachAllOnCommit(getDetachAllOnCommit());
obj.setMultithreaded(getMultithreaded());
return obj;
}
// public boolean getAllowNonStandardSCOs() {
// return allowNonStandardSCOs;
// }
/**
* @return Whether to auto create schemas.
* @see ZooConstants#PROPERTY_AUTO_CREATE_SCHEMA
*/
public boolean getAutoCreateSchema() {
return autoCreateSchema;
}
/**
* @return Whether to evict primitives.
* @see ZooConstants#PROPERTY_EVICT_PRIMITIVES
*/
public boolean getEvictPrimitives() {
return evictPrimitives;
}
/**
* @return Whether to fail on closed queries.
* @see ZooConstants#PROPERTY_FAIL_ON_CLOSED_QUERIES
*/
public boolean getFailOnClosedQueries() {
return failOnClosedQueries;
}
}