/* * Copyright (C) 2009 Muthu Ramadoss. All rights reserved. * * Modified from Romain Guy Shelves project to suit Books-Exchange requirements. * Original source from Shelves - http://code.google.com/p/shelves/ */ /* * Copyright (C) 2008 Romain Guy * * 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. */ package com.androidrocks.bex.provider; import android.content.Context; import android.content.SharedPreferences; import android.content.res.XmlResourceParser; import android.content.res.TypedArray; import android.util.Xml; import android.util.AttributeSet; import android.util.Log; import android.view.InflateException; import android.text.TextUtils; import java.util.HashMap; import java.util.Map; import java.util.Iterator; import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import com.androidrocks.bex.util.Preferences; import com.androidrocks.bex.R; import org.xmlpull.v1.XmlPullParserException; import static org.xmlpull.v1.XmlPullParser.*; public final class BookStoreFactory { private static final String LOG_TAG = "ShelvesParser"; public static final String DEFAULT_BOOK_STORE = "all"; private static final String TAG_STORES = "stores"; private static final String TAG_STORE = "store"; private static HashMap<String, BooksStore> sStores; private BookStoreFactory() { } public static BooksStore get(Context context) { final SharedPreferences preferences = context.getSharedPreferences(Preferences.NAME, 0); final String name = preferences.getString(Preferences.KEY_BOOKSTORE, DEFAULT_BOOK_STORE); BooksStore store = get(context, name); if (store == null) { final Iterator<Map.Entry<String, BooksStore>> iterator = sStores.entrySet().iterator(); if (iterator.hasNext()) { store = iterator.next().getValue(); final SharedPreferences.Editor editor = preferences.edit(); editor.putString(Preferences.KEY_BOOKSTORE, store.getName()); editor.commit(); return store; } } return store; } public static BooksStore get(Context context, String store) { if (sStores == null) { sStores = inflate(context, R.xml.bookstores); } BooksStore booksStore = sStores.get(store); if (booksStore == null) throw new IllegalStateException("The store " + store + " cannot not be found"); return booksStore; } public static BooksStore[] getStores(Context context) { if (sStores == null) { sStores = inflate(context, R.xml.bookstores); } return sStores.values().toArray(new BooksStore[sStores.size()]); } private static HashMap<String, BooksStore> inflate(Context context, int resource) { final HashMap<String, BooksStore> stores = new HashMap<String, BooksStore>(); final XmlResourceParser parser = context.getResources().getXml(resource); try { inflate(context, parser, stores); } catch (IOException e) { Log.w(LOG_TAG, "An error occured while loading the bookstores", e); } catch (XmlPullParserException e) { Log.w(LOG_TAG, "An error occured while loading the bookstores", e); } finally { parser.close(); } if (stores.size() >= 1) { final CompoundBooksStore store = new CompoundBooksStore(context, stores); stores.put(store.getName(), store); } return stores; } private static void inflate(Context context, XmlResourceParser parser, HashMap<String, BooksStore> stores) throws IOException, XmlPullParserException { final AttributeSet attrs = Xml.asAttributeSet(parser); int type; while ((type = parser.next()) != START_TAG && type != END_DOCUMENT) { // Empty } if (type != START_TAG) { throw new InflateException(parser.getPositionDescription() + ": No start tag found!"); } final String name = parser.getName(); if (TAG_STORES.equals(name)) { parseStores(context, parser, attrs, stores); } else { throw new InflateException(parser.getPositionDescription() + ": The root tag must be " + TAG_STORES); } } private static void parseStores(Context context, XmlResourceParser parser, AttributeSet attrs, HashMap<String, BooksStore> stores) throws IOException, XmlPullParserException { final int depth = parser.getDepth(); int type; while (((type = parser.next()) != END_TAG || parser.getDepth() > depth) && type != END_DOCUMENT) { if (type != START_TAG) { continue; } final String name = parser.getName(); if (TAG_STORE.equals(name)) { addStore(context, parser, attrs, stores); } } } private static void addStore(Context context, XmlResourceParser parser, AttributeSet attrs, HashMap<String, BooksStore> stores) { TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.BookStore); final String name = a.getString(R.styleable.BookStore_name); if (TextUtils.isEmpty(name)) { throw new InflateException(parser.getPositionDescription() + ": A store must have a name"); } final String label = a.getString(R.styleable.BookStore_label); if (TextUtils.isEmpty(label)) { throw new InflateException(parser.getPositionDescription() + ": A store must have a label"); } final String storeClass = a.getString(R.styleable.BookStore_storeClass); if (TextUtils.isEmpty(name)) { throw new InflateException(parser.getPositionDescription() + ": A store must have a class"); } a.recycle(); try { Class<?> klass = Class.forName(storeClass); Constructor<?> constructor = klass.getDeclaredConstructor(String.class, String.class); constructor.setAccessible(true); BooksStore store = (BooksStore) constructor.newInstance(name, label); stores.put(name, store); } catch (ClassNotFoundException e) { // Ignore } catch (NoSuchMethodException e) { throw new InflateException(parser.getPositionDescription() + ": The book store " + storeClass + " does not have a matching constructor"); } catch (IllegalAccessException e) { throw new InflateException(parser.getPositionDescription() + ": Could not create the " + "book store", e); } catch (InvocationTargetException e) { throw new InflateException(parser.getPositionDescription() + ": Could not create the " + "book store", e); } catch (InstantiationException e) { throw new InflateException(parser.getPositionDescription() + ": Could not create the " + "book store", e); } } }