Configuration not being reloaded - java

I'm having an issue with my configuration management class, it is not getting reloaded.
Let me show you part of my code:
public class ConfigurationManager extends XMLConfiguration
{
private static final Logger log = LoggerFactory.getLogger(ConfigurationManager.class);
private static final long serialVersionUID = 1L;
public static final String CONFIG_FILE_PATH = "/config.xml";
private static volatile ConfigurationManager instance = null;
private static Object lock = new Object();
// Instance management methods
public static ConfigurationManager getInstance()
{
return getInstance(CONFIG_FILE_PATH);
}
public static ConfigurationManager getInstance(String cfg)
{
if(instance == null)
{
synchronized(lock)
{
if(instance == null)
{
try
{
instance = new ConfigurationManager(cfg);
instance.dumpConfigurationToLog();
}
catch(Exception e)
{
log.error("Error calling getInstance. Method params", e);
}
}
}
}
return instance;
}
private Object loadedCfg;
private int reloadInterval;
private void dumpConfigurationToLog()
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try
{
this.save(bos);
bos.flush();
}
catch(Exception e)
{
log.error("Error calling dumpConfigurationToLog. Method params", e);
}
}
#Override
public void configurationChanged(ConfigurationEvent event)
{
log.info("Enter Method configurationChanged params: {}", event);
if(event.isBeforeUpdate() == false)
{
makeUpdates();
log.info("Configuration file: {} has changed and reloaded...", loadedCfg);
dumpConfigurationToLog();
}
log.info("Return Method configurationChanged");
}
private void updateReloadInterval()
{
int newReloadInterval = getInt("global.reloadInterval") * 1000;
if(reloadInterval != newReloadInterval)
{
reloadInterval = newReloadInterval;
if(getReloadInterval() > 0)
{
FileChangedReloadingStrategy reloadStrategy = new FileChangedReloadingStrategy();
reloadStrategy.setRefreshDelay(getReloadInterval());
this.setReloadingStrategy(reloadStrategy);
}
else
if(getReloadInterval() == 0)
{
this.setReloadingStrategy(new InvariantReloadingStrategy());
}
else
{
log.error("Invalid reload interval for ConfigurationManager: {}", getReloadInterval());
}
}
}
private ConfigurationManager(String cfgFile) throws Exception, ConfigurationException
{
super();
loadedCfg = cfgFile;
if(System.class.getResource(cfgFile) != null)
this.setURL(System.class.getResource(cfgFile));
else
this.setURL(getClass().getResource(cfgFile));
this.load();
makeUpdates();
this.addConfigurationListener(this);
this.setThrowExceptionOnMissing(true);
}
private void makeUpdates()
{
updateReloadInterval();
}
public int getReloadInterval()
{
return reloadInterval;
}
}
Now that code works perfectly fine, I can read the configuration file, and work with it with no major problems, the issue is that it never gets reloaded on configuration changes. I've tried setting breakpoints and so, but it never gets into configurationChanged method.
Does anybody see something wrong here?

Well, after testing and analyzing, I've got to this conclusion, in order to have configurationChanged called, I need to make an explicit call to get values from configuration.
And that is something I was not doing.
The thing got fixed when I did that.

You're calling makeUpdates() after setting your ConfigurationListener.
Additionally, calling load() is no guarantee that an Event will get fired.
Lastly, is there anything actually calling addProperty(), etc for this extended class?

Only a small side issue: resource bundles are cached, you can call clearCache, unfortunately not per bundle but per class loader.

Related

How to test void method with no parameters?

I have method that is called by another service and it just change one of the field for some rows in database. Method looks like this:
void errorOrders() {
List<Orders> orders = OrderDAO.getErrorOrders(); //select only fields with status 'error'
orders.forEach(order -> order.setStatus(OrderStatus.NEW);
//some logging etc.
}
Is there any way to unit test this method? Can I inject myself inside this method and check if orders status was changed?
Cheers!
I would recommend you refactor your class to make your code testable. Ideally you would inject the dependency that represents the OrderDAO:
class ErrorChecker {
private final OrderDAO orderDAO;
public ErrorChecker(OrderDAO orderDAO) {
this.orderDAO = orderDAO;
}
public void errorOrders() {
List<Orders> orders = orderDAO.getErrorOrders();
orders.forEach(order -> order.setStatus(OrderStatus.NEW);
}
}
Then your test code would look like:
#Test
void testErrorOrders() {
Order order1 = mock(Order.class);
Order order2 = mock(Order.class);
OrderDAO orderDAO = mock(OrderDAO.class);
when(orderDAO.getErrorOrders()).thenReturn(List.of(order1, order2));
ErrorChecker errorChecker = new ErrorChecker(orderDAO);
errorChecker.errorOrders();
verify(order1).setState(OrderStatus.NEW);
verify(order2).setState(OrderStatus.NEW);
}
There are ways to mock static methods but I would recommend refactoring to inject the dependencies as it has many other benefits beside testability.
If you need to leave the method as static then you can still mock it (in v3.4+ of Mockito):
#Test
void testErrorOrders() {
try (MockedStatic mocked = mockStatic(OrderDAO.class)) {
mocked.when(OrderDAO.getErrorOrders()).thenReturn(List.of(order1, order2));
ErrorChecker errorChecker = new ErrorChecker(orderDAO);
errorChecker.errorOrders();
mocked.verify(order1).setState(OrderStatus.NEW);
}
}
#ismail and #khelwood already provided good answers.
If you mock the Object, you can control/see what happens to it
If you change an Object, where you can access the state via public methods, use those
If you change an Object whose state you cannot access with normal code, use Java Reflections to look at member variables.
If you set up Objects, that pass their data to streams and other output, you can put some additional streams etc in between. Use inheritance and reflection if necessary
Simple example of using Reflection on a shielded class:
package stackoverflow.simplefieldaccess;
public class ShieldedClass {
private int mStatus;
public ShieldedClass() {
mStatus = 666;
}
public void setStatus(final int pStatus) {
mStatus = pStatus; // usually with ints be careful and do checks here, but for the sake of simplicity we leave that out
}
#Override public String toString() {
return getClass().getSimpleName() + "[status:" + mStatus + "]";
}
}
Code to access it via reflection in a few ways:
package stackoverflow.simplefieldaccess;
import java.lang.reflect.Field;
import jc.lib.lang.reflect.JcFieldAccess;
public class SimpleFieldAccess {
public static void main(final String[] args) throws NoSuchFieldException, SecurityException {
final ShieldedClass so = new ShieldedClass();
System.out.println("Object.status before change: " + so);
so.setStatus(667);
System.out.println("Object.status after change: " + so);
System.out.println();
System.out.println("Accessing Object.status via Reflection...");
final Class<? extends ShieldedClass> cls = so.getClass();
final Field fieldToChance = cls.getDeclaredField("mStatus");
{
System.out.println("\nBad read access");
try { // will result in java.lang.IllegalAccessException
System.out.println("\tReading Object.status fiels via Reflection: " + fieldToChance.getInt(so));
throw new IllegalStateException("UNEXOECTED ERROR!");
} catch (final java.lang.IllegalAccessException e) {
System.out.println("\tAs expected: IllegalAccessException");
}
}
{
System.out.println("\nBad write access");
try { // will result in java.lang.IllegalAccessException
fieldToChance.set(so, Integer.valueOf(1337));
System.out.println("\tObject.status after change: " + so);
} catch (final java.lang.IllegalAccessException e) {
System.out.println("\tAs expected: IllegalAccessException");
}
}
{
System.out.println("\nGood manual read and write access");
final boolean isFieldOriginallyAccessible = fieldToChance.isAccessible();
try { // will result in java.lang.IllegalAccessException
if (!isFieldOriginallyAccessible) fieldToChance.setAccessible(true);
System.out.println("\tReading Object.status field via Reflection: " + fieldToChance.getInt(so));
fieldToChance.set(so, Integer.valueOf(4321));
System.out.println("\tObject.status after change: " + so);
} catch (final java.lang.IllegalAccessException e) {
e.printStackTrace();
} finally {
if (!isFieldOriginallyAccessible) fieldToChance.setAccessible(false);
}
}
{
System.out.println("\nGood automated read and write access");
try (JcFieldAccess fa = new JcFieldAccess(fieldToChance)) { // will result in java.lang.IllegalAccessException
System.out.println("\tReading Object.status field via Reflection: " + fieldToChance.getInt(so));
fieldToChance.set(so, Integer.valueOf(123));
System.out.println("\tObject.status after change: " + so);
} catch (final java.lang.IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
For reflections, when I want to access fields, I use my homebrew class that makes it easier to get access to the field and afterwards restore it to normal (last example above uses this):
package jc.lib.lang.reflect;
import java.io.Closeable;
import java.lang.reflect.AccessibleObject;
public class JcFieldAccess implements Closeable {
private final AccessibleObject mField;
private final boolean mIsAccessible;
public JcFieldAccess(final AccessibleObject pField) {
mField = pField;
mIsAccessible = mField.isAccessible();
if (!mIsAccessible) mField.setAccessible(true);
}
#Override public void close() {
if (mIsAccessible) return;
if (mField != null) mField.setAccessible(false);
}
}
The trick with this util class is that when used in a try-resource block, its close() method will get called automatically, whether the block fails or not. It's the same as having the close() or in this case setAccessible(false) call in the finally block, with some extra checks.
Let the class be:
class HandleErrorOrders {
private OrderDAO orderDAO;
HandleErrorOrders(final OrderDAO orderDAO) {
this.orderDAO = orderDAO;
}
public void errorOrders() {
List<Orders> orders = OrderDAO.getErrorOrders(); //select only fields with status 'error'
orders.forEach(order -> order.setStatus(OrderStatus.NEW);
//some logging etc.
}
}
You need to use assert methods to check end state.
To test, write something like:
class HandleErrorOrdersTest {
#Mock
private OrderDAO orderDAO;
#InjectMocks
private HandleErrorOrders handleErrorOrders;
#Test
void testErrorOrders() {
Order order1 = mock(Order.class);
Order order2 = mock(Order.class);
when(orderDAO.getErrorOrders()).thenReturn(List.of(order1, order2));
ErrorChecker errorChecker = new ErrorChecker(orderDAO);
errorChecker.errorOrders();
//asset checks
Assert.assertEquals(OrderStatus.NEW, order1.getStatus());
Assert.assertEquals(OrderStatus.NEW, order2.getStatus());
//verification checks
Mockito.verify(orderDAO).getErrorOrders();
}
}

Cache handling with RXJava

I'm trying to implement this workflow with rxJava but i'm sure if i'm misusing or doing stuff wrong.
User asks to login
If a loginResult is available in cache then "emit" the cached LoginResult
Else actually perform the request to the webservice and cache the result if everything is successfull
If an error occurs retry at most 3 times and if there is a 4th time then purge the cache.
Here is my full snippet of code.
public class LoginTask extends BaseBackground<LoginResult> {
private static CachedLoginResult cachedLoginResult = new CachedLoginResult();
private XMLRPCClient xmlrpcClient;
private UserCredentialsHolder userCredentialsHolder;
#Inject
public LoginTask(XMLRPCClient client, UserCredentialsHolder userCredentialsHolder) {
this.xmlrpcClient = client;
this.userCredentialsHolder = userCredentialsHolder;
}
#Override
public LoginResult performRequest() throws Exception {
return UserApi.login(
xmlrpcClient,
userCredentialsHolder.getUserName(),
userCredentialsHolder.getPlainPassword());
}
#Override
public Observable<LoginResult> getObservable() {
return cachedLoginResult.getObservable()
.onErrorResumeNext(
Observable.create(
((Observable.OnSubscribe<LoginResult>) subscriber -> {
try {
if (!subscriber.isUnsubscribed()) {
subscriber.onNext(performRequest()); // actually performRequest
}
subscriber.onCompleted();
} catch (Exception e) {
subscriber.onError(e);
}
})
)
.doOnNext(cachedLoginResult::setLoginResult)
.retry((attempts, t) -> attempts < 3)
.doOnError(throwable -> cachedLoginResult.purgeCache())
);
}
private static class CachedLoginResult {
private LoginResult lr = null;
private long when = 0;
private CachedLoginResult() {
}
public boolean hasCache() {
return lr != null && when + TimeUnit.MILLISECONDS.convert(30, TimeUnit.MINUTES) > System.currentTimeMillis();
}
public void setLoginResult(LoginResult lr) {
if (lr != null) {
this.lr = lr;
this.when = System.currentTimeMillis();
}
}
public void purgeCache() {
this.lr = null;
this.when = 0;
}
public Observable<LoginResult> getObservable() {
return Observable.create(new Observable.OnSubscribe<LoginResult>() {
#Override
public void call(Subscriber<? super LoginResult> subscriber) {
if (!subscriber.isUnsubscribed()) {
if (hasCache()) {
subscriber.onNext(lr);
subscriber.onCompleted();
} else {
subscriber.onError(new RuntimeException("No cache"));
}
}
}
});
}
}
}
Since i wan't able to find any similar examples and i started "playing" with rxjava just 1 day ago i'm unsure of my implementation.
Thank you for your time.
I think this code is alright, good job :)
You were right to use Observable.create in your LoginTask because otherwise result of the call could be cached internally, and then retry wouldn't help much...
This is I think however unnecessary for the CachedLoginResult's Observable. Here you can simplify your code by using Observable.justand Observable.error utility methods, something like:
public Observable<LoginResult> getObservable() {
if (hasCache()) {
return Observable.just(lr);
} else {
return Observable.error(new RuntimeException("No cache"));
}
}
Note: just stores the value you tell it to emit internally, so that resubscriptions will always produce this value. This is what I hinted above, you shouldn't do Observable.just(performRequest()).retry(3) for example, because the performRequest will only ever be called once.
If I understand correctly, you want to perform the login once and cache the result in a reactive manner? If so, here is an example how I would do this:
import java.util.concurrent.ThreadLocalRandom;
import rx.*;
import rx.schedulers.Schedulers;
import rx.subjects.AsyncSubject;
public class CachingLogin {
static class LoginResult {
}
/** Guarded by this. */
AsyncSubject<LoginResult> cache;
public Observable<LoginResult> login(String username, String password) {
AsyncSubject<LoginResult> c;
boolean doLogin = false;
synchronized (this) {
if (cache == null || cache.hasThrowable()) {
cache = AsyncSubject.create();
doLogin = true;
}
c = cache;
}
if (doLogin) {
Observable.just(1).subscribeOn(Schedulers.io())
.map(v -> loginAPI(username, password))
.retry(3).subscribe(c);
}
return c;
}
public void purgeCache() {
synchronized (this) {
cache = null;
}
}
static LoginResult loginAPI(String username, String password) {
if (ThreadLocalRandom.current().nextDouble() < 0.3) {
throw new RuntimeException("Failed");
}
return new LoginResult();
}
}

Catch Win32 Event with Java JNA

I am solving this issue:
In my Java application (installed on Windows OS machine) I have to catch Win32 Event which is created by another application on same machine. This app is written in C++ and there is no way to change it. I have information that I have to use OpenEvent function. I started as is metioned in:
Calling OpenEvent fails through JNA
Here is my code:
public class WinEventListener {
private Logger logger = LoggerFactory.getLogger(WinEventListener.class);
static {
Native.register("kernel32");
}
public static native HANDLE OpenEventW(int access, boolean inheritHandle, WString name);
public static native int WaitForSingleObject(HANDLE hHandle, int dwMilliseconds);
public static native boolean CloseHandle(HANDLE hObject);
public static class HANDLE extends PointerType {
public Object fromNative(Object nativeValue, FromNativeContext context) {
Object o = super.fromNative(nativeValue, context);
if (INVALID_HANDLE_VALUE.equals(o))
return INVALID_HANDLE_VALUE;
return o;
}
}
static HANDLE INVALID_HANDLE_VALUE = new HANDLE() {
{
super.setPointer(Pointer.createConstant(-1));
}
public void setPointer(Pointer p) {
throw new UnsupportedOperationException("Immutable reference");
}
};
public void listen() throws Exception {
HANDLE handle = null;
do {
//logger.debug("Wainting for handle");
handle = OpenEventW(2, false, new WString("VLIT_SERVER_DATA"));
logger.debug("Handle:" + handle.toString());
Thread.sleep(1000);
} while (handle == null);
logger.debug("Handle obtained");
while(true){
int result = WaitForSingleObject(handle,Integer.MAX_VALUE);
if(result == 0){
logger.debug("Handle signalized");
VLITProcceserThread thread = new VLITProcceserThread();
thread.start();
CloseHandle(handle);
}
}
}
}
Basiclly I want in listen() method wait for HANDLE create by other program and if its created then wait for its signalized state, do some action and release handle.
BUt I have no success. Can anybody point me to right way?
Thans a lot!
If it is the opening of the handle that is failing it is most likely an issue with privileges. Is your program running as a service? I was trying to do something similar and was able to get this program running and working when i called it via a system call inside a program that was running as a service.
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.PointerType;
import com.sun.jna.WString;
import com.sun.jna.FromNativeContext;
public class WinEventListener {
static {
Native.register("kernel32");
}
public static native HANDLE OpenEventW(int access, boolean inheritHandle, WString name);
public static native int WaitForSingleObject(HANDLE hHandle, int dwMilliseconds);
public static native boolean CloseHandle(HANDLE hObject);
public static class HANDLE extends PointerType {
public Object fromNative(Object nativeValue, FromNativeContext context) {
Object o = super.fromNative(nativeValue, context);
if (INVALID_HANDLE_VALUE.equals(o))
return INVALID_HANDLE_VALUE;
return o;
}
}
static HANDLE INVALID_HANDLE_VALUE = new HANDLE() {
{
super.setPointer(Pointer.createConstant(-1));
}
public void setPointer(Pointer p) {
throw new UnsupportedOperationException("Immutable reference");
}
};
public void listen() {
try {
HANDLE handle = null;
do {
handle = OpenEventW(2031619, false, new WString("event_name"));
if(handle == null) {
System.out.print("Handle is null\n");
}
Thread.sleep(500);
} while (handle == null);
while(true){
// 50 second timeout
int result = WaitForSingleObject(handle, 50000);
if(result == 0){
System.out.print("Handle signaled\n");
}
else if (result == 258){
System.out.print("Timed out\n");
}
else{
System.out.print("Handle not signaled\n");
System.out.print(result);
}
System.out.print(result);
//System.out.print(handle);
Thread.sleep(100);
}
}
catch (Exception exc)
{
System.out.print(exc);
//Thread.sleep(10000);
//writer.writeln(exc);
}
}
public static void main(String[] args) {
WinEventListener listener = new WinEventListener();
listener.listen();
}
}

How to call parent class objects within a subclass?

I'm not sure if I'm asking this right, as I'm attempting to teach myself Java. I have a class which contains my main method, and within this class are several subclasses that need access to my user settings using java.util.Properties. I have to create the properties object in every subclass in order to make it work, and I can't reference the object using configFilePath, it must be null. I'm wondering if I can create this public object within the parent class, so I don't need to create it in all of its subclasses? Here is my code, I'm really not sure I'm doing this right although it works.
public class Frame1 extends JFrame {
Settings config = new Settings(); //this is the object I want to reference within subclasses
class Update extends SwingWorker<Integer, Void> { //first subclass
#Override
protected Integer doInBackground() throws Exception {
Settings config = new Settings(configFilePath); //yet I have to create the object within every subclass, this time an argument is required.
String templateDir = config.getProperty("templatedir");
String writePath = config.getProperty("outputdir");
//do some logic code, not required for my question
}
#Override
protected void done() {
Update2 update2 = new Update2();
update2.execute(); //start the next subclass which also needs access to Settings(configFilePath)
}
}
}
public class Settings extends JFrame {
String configFilePath = "C:/path/to/settings.properties";
Properties properties = new Properties();
public Settings(String configFilePath) throws IOException {
this.configFilePath = configFilePath;
FileInputStream fis = null;
try {
fis = new FileInputStream(configFilePath);
properties.load(fis);
} catch (FileNotFoundException e) {
setDefaults();
} finally {
if (fis != null) {
fis.close();
}
}
}
}
I'm not sure if I'm doing this right or not, it seems to work but seems to be rather redundant having to create the config object every time I need to access my user settings. I hope this hasn't been asked before, and if it has please link me, as I could not find it.
You can create the Setting class as a Singleton pattern, here is one example:
public class Settings extends JFrame{
String configFilePath = "C:/path/to/settings.properties";
Properties properties = new Properties();
private static Settings instance;
public static Settings getInstance(){
if(instance==null){
instance = new Setting();
}
return instance;
}
private Settings() throws IOException {
FileInputStream fis = null;
try {
fis = new FileInputStream(configFilePath);
properties.load(fis);
} catch (FileNotFoundException e) {
setDefaults();
} finally {
if (fis != null) {
fis.close();
}
}
}
}
Usage in any other class of your system:
Settings.getInstance().getProperty("...");
From Update you can use Frame1.this to access the this of Frame1 (because Update is an inner class of Frame1).
Then to access config you can use Frame1.this.config.
Here is a working example:
public class PrefixerFactory {
private String prefix; // Used by Prefixer
public PrefixerFactory(String prefix) {
this.prefix = prefix;
}
public Prefixer createPrefixer() {
return new Prefixer();
}
public class Prefixer { // Inner class
public String addPrefix(String value) {
// Using "prefix" from PrefixerFactory
return PrefixerFactory.this.prefix + value;
}
}
public static void main(String[] args) {
Prefixer helloPrefixer = new PrefixerFactory("Hello ").createPrefixer();
Prefixer goodbyePrefixer = new PrefixerFactory("Good bye ").createPrefixer();
System.out.println(helloPrefixer.addPrefix("world")); // Hello world
System.out.println(goodbyePrefixer.addPrefix("world")); // Good bye world
}
}

Is it good have a DatabaseManager with all of the functions from all the model objects?

I'working on a db application with ORmlite, my model is like this:
MDL object..
DatabaseTable(tableName = "UserCars")
public class CarMDL
{
#DatabaseField(generatedId = true)
private int _id;
#DatabaseField(columnName = "name")
private String _name;
//................. etc
}
// DB Helper class...
public class DatabaseHelper extends OrmLiteSqliteOpenHelper
{
private Dao<CarMDL,Integer> _carDao = null;
#Override
public void onCreate(SQLiteDatabase database,ConnectionSource connectionSource)
{
try
{
TableUtils.createTable(connectionSource, CarMDL.class);
} catch (SQLException e)
{
throw new RuntimeException(e);
} catch (java.sql.SQLException e)
{
e.printStackTrace();
}
}
public Dao<CarMDL, Integer> getCarDao()
{
if (null == _carDao)
{
try
{
_carDao = getDao(CarMDL.class);
}catch (java.sql.SQLException e)
{
e.printStackTrace();
}
}
return _carDao;
}
}
// DatabaseManager class...
public class DatabaseManager
{
static private DatabaseManager instance;
private DatabaseHelper helper;
static public void init(Context ctx)
{
if (null == instance)
{
instance = new DatabaseManager(ctx);
}
}
static public DatabaseManager getInstance()
{
return instance;
}
private DatabaseManager(Context ctx)
{
helper = new DatabaseHelper(ctx);
}
private DatabaseHelper getHelper()
{
return helper;
}
// All the Dao functions of all MDL objects are in this class, for example:
public List<CarMDL> getAllCars()
{
List<CarMDL> carLists = null;
try
{
carLists = getHelper().getCarDao().queryForAll();
} catch (SQLException e)
{
e.printStackTrace();
}
return carLists;
}
// This is another MDL object..
public List<MarkMDL> getAllMarks()
{
List<MarkMDL> marks = null;
try
{
marks = getHelper().getMarkDao().queryForAll();
} catch (SQLException e)
{
e.printStackTrace();
}
return marks;
}
}
So my question is, is it good have a DatabaseManager with all the functions from all the model objects, like:
listCarById(int id)
listPlaneById(int id)
removeCar(int id)
removePlane(int id)
Etc.....
Updated per Gray's comment.
Be careful with your "singleton" implementation. Your init method should be synchronized to ensure that you don't end up with multiple instances of your DatabaseManager class due to concurrency issues. I would just combine the init and getInstance methods to the following (note the added synchronized keyword):
public static synchronized DatabaseManager getInstance(Context c)
{
if(instance == null)
instance = new DatabaseManager(c);
return instance;
}
For further reading, check out these blog posts about Single SQLite Connection and Android Sqlite locking by Kevin Galligan (one of the contributors to ORMlite).
Update:
To answer your question about how to organize your loading methods like getAllCars, I would first suggest making them static, since they do not depend on anything else besides your method to get your singleton of DatabaseManager, which of course, would also be static. If you have a small number of these types of methods, you could make them all static members of DatabaseManger. If you have many, you could make a helper class for all static methods corresponding to a type.
If you have a method that does depend on the internals of a given instance of CarMDL or MarkMDL (like you need a method to get some associated references), consider making these methods members of the CarMDL or MarkMDL class.
I put all my one-time-per-app work in Application onCreate and I keep a reference of the application instance itself, so I can do many tasks without having to mess with synchronized methods or similar. So let's say we have an Application (remember to add it in the manifest):
public class App extends Application
{
private static App gInstance = null;
// your static globals here
#Override
public void onCreate()
{
// according to documentation onCreate is called before any other method
super.onCreate();
// assign here all your static stuff
gInstance = this;
}
// doesn't need to be synchronized because of the early onCreate
public static App getInstance()
{
return gInstance;
}
}
then your database helper class, Manifest.class is an array of all of your datatype classes:
public class DatabaseHelper extends OrmLiteSqliteOpenHelper
{
// private constructor, singleton pattern, we use
// App context so the class is created on static init
private static DatabaseHelper gHelper = new DatabaseHelper(App.getInstance());
private DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION, R.raw.ormlite_config);
// cache your dao here
for (Class<?> cls: Manifest.classes)
{
try
{
DaoManager.createDao(getConnectionSource(), cls);
} catch (SQLException e)
{
e.printStackTrace();
}
}
}
// if you need the instance, you don't need synchronized because of static init
public static DatabaseHelper getHelper()
{
return gHelper;
}
// lookup from cache
public static <D extends Dao<T, ?>, T> D getTypeDao(Class<T> cls)
{
return DaoManager.lookupDao(gHelper.getConnectionSource(), cls);
}
// we leak this class here since android doesn't provide Application onDestroy
// it's not really a big deal if we need the orm mapping for all application lifetime
// Q: should I keep the instance closeable? the android finalyzer calls somehow close here? I was unable to reproduce, to be sure you can call the super.close() and print a warning
#Override
public void close()
{
throw new RuntimeException("DatabaseHelper Singleton is ethernal");
}
}
addd the context to your DatabaseManager method
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DatabaseManager.init(this.getContext());
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
example android app with ormlite
https://github.com/elberthcabrales/cfeMedicion

Categories