killbill-memoizeit
Changes
catalog/src/main/java/com/ning/billing/catalog/Catalog.java 260(+131 -129)
Details
catalog/src/main/java/com/ning/billing/catalog/Catalog.java 260(+131 -129)
diff --git a/catalog/src/main/java/com/ning/billing/catalog/Catalog.java b/catalog/src/main/java/com/ning/billing/catalog/Catalog.java
index fa24752..bbc9485 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/Catalog.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/Catalog.java
@@ -63,7 +63,7 @@ public class Catalog extends ValidatingConfig<Catalog> implements ICatalog {
private Product[] products;
@XmlElement(name="rules", required=true)
- private PlanRules planRules;
+ private PlanRules planRules;
@XmlElementWrapper(name="plans", required=true)
@XmlElement(name="plan", required=true)
@@ -78,163 +78,114 @@ public class Catalog extends ValidatingConfig<Catalog> implements ICatalog {
this.effectiveDate = effectiveDate;
}
- @Override
- public void initialize(Catalog catalog, URI sourceURI) {
- catalogURI = sourceURI;
- super.initialize(catalog, sourceURI);
- planRules.initialize(catalog, sourceURI);
- priceLists.initialize(catalog, sourceURI);
- for(Product p : products) {
- p.initialize(catalog, sourceURI);
- }
- for(Plan p : plans) {
- p.initialize(catalog, sourceURI);
- }
- }
-
- /* (non-Javadoc)
+ /* (non-Javadoc)
* @see com.ning.billing.catalog.ICatalog#getCalalogName()
*/
- @Override
+ @Override
public String getCalalogName() {
return catalogName;
}
- /* (non-Javadoc)
+ /* (non-Javadoc)
* @see com.ning.billing.catalog.ICatalog#getProducts()
*/
- @Override
+ @Override
public Product[] getProducts() {
return products;
}
- public void setProducts(Product[] products) {
- this.products = products;
- }
-
-
- /* (non-Javadoc)
+ /* (non-Javadoc)
* @see com.ning.billing.catalog.ICatalog#getPlan(java.lang.String, java.lang.String)
*/
- @Override
+ @Override
public Plan getPlan(String productName, BillingPeriod period, String priceListName) {
- IProduct product = getProductFromName(productName);
- return priceLists.getPlanListFrom(priceListName, product, period);
- }
+ IProduct product = getProductFromName(productName);
+ return priceLists.getPlanListFrom(priceListName, product, period);
+ }
@Override
public Currency[] getSupportedCurrencies() {
return supportedCurrencies;
}
- public void setSupportedCurrencies(Currency[] supportedCurrencies) {
- this.supportedCurrencies = supportedCurrencies;
+ @Override
+ public Plan[] getPlans() {
+ return plans;
+ }
+ @Override
+ public ActionPolicy getPlanChangePolicy(PlanPhaseSpecifier from, PlanSpecifier to) {
+ return planRules.getPlanChangePolicy(from, to, this);
}
- public void setPlanChangeRules(PlanRules planChangeRules) {
- this.planRules = planChangeRules;
+ @Override
+ public PlanAlignmentChange getPlanChangeAlignment(PlanPhaseSpecifier from, PlanSpecifier to) {
+ return planRules.getPlanChangeAlignment(from, to, this);
}
@Override
- public Plan[] getPlans() {
- return plans;
+ public ActionPolicy getPlanCancelPolicy(PlanPhaseSpecifier planPhase) {
+ return planRules.getPlanCancelPolicy(planPhase, this);
}
- public void setPlans(Plan[] plans) {
- this.plans = plans;
+ @Override
+ public PlanAlignmentCreate getPlanCreateAlignment(PlanSpecifier specifier) {
+ return planRules.getPlanCreateAlignment(specifier, this);
}
@Override
- public ValidationErrors validate(Catalog catalog, ValidationErrors errors) {
- validate(catalog,errors, products);
- validate(catalog,errors, plans);
- priceLists.validate(catalog,errors);
- planRules.validate(catalog, errors);
- return errors;
+ public BillingAlignment getBillingAlignment(PlanPhaseSpecifier planPhase) {
+ return planRules.getBillingAlignment(planPhase, this);
}
- private Collection<? extends ValidationError> validate(Catalog catalog,
- ValidationErrors errors, ValidatingConfig<Catalog>[] configs) {
- for(ValidatingConfig<Catalog> config: configs) {
-
+
+ @Override
+ public Plan getPlanFromName(String name) {
+ if (name == null) {
+ return null;
+ }
+ for(Plan p : plans) {
+ if(p.getName().equals(name)) {
+ return p;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public IProduct getProductFromName(String name) {
+ for(Product p : products) {
+ if (p.getName().equals(name)) {
+ return p;
+ }
}
return null;
}
+
+ @Override
+ public PlanPhase getPhaseFromName(String name) {
+
+ if (name == null) {
+ return null;
+ }
+ for(Plan p : plans) {
+
+ if(p.getFinalPhase().getName().equals(name)) {
+ return p.getFinalPhase();
+ }
+ if (p.getInitialPhases() != null) {
+ for(PlanPhase pp : p.getInitialPhases()) {
+ if(pp.getName().equals(name)) {
+ return pp;
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
@Override
- public ActionPolicy getPlanChangePolicy(PlanPhaseSpecifier from, PlanSpecifier to) {
- return planRules.getPlanChangePolicy(from, to, this);
- }
-
- @Override
- public PlanAlignmentChange getPlanChangeAlignment(PlanPhaseSpecifier from, PlanSpecifier to) {
- return planRules.getPlanChangeAlignment(from, to, this);
- }
-
- @Override
- public ActionPolicy getPlanCancelPolicy(PlanPhaseSpecifier planPhase) {
- return planRules.getPlanCancelPolicy(planPhase, this);
- }
-
- @Override
- public PlanAlignmentCreate getPlanCreateAlignment(PlanSpecifier specifier) {
- return planRules.getPlanCreateAlignment(specifier, this);
- }
-
- @Override
- public BillingAlignment getBillingAlignment(PlanPhaseSpecifier planPhase) {
- return planRules.getBillingAlignment(planPhase, this);
- }
-
-
- @Override
- public Plan getPlanFromName(String name) {
- if (name == null) {
- return null;
- }
- for(Plan p : plans) {
- if(p.getName().equals(name)) {
- return p;
- }
- }
- return null;
- }
-
- @Override
- public IProduct getProductFromName(String name) {
- for(Product p : products) {
- if (p.getName().equals(name)) {
- return p;
- }
- }
- return null;
- }
-
-
- @Override
- public PlanPhase getPhaseFromName(String name) {
-
- if (name == null) {
- return null;
- }
- for(Plan p : plans) {
-
- if(p.getFinalPhase().getName().equals(name)) {
- return p.getFinalPhase();
- }
- if (p.getInitialPhases() != null) {
- for(PlanPhase pp : p.getInitialPhases()) {
- if(pp.getName().equals(name)) {
- return pp;
- }
- }
- }
- }
-
- return null;
- }
-
- @Override
public Date getEffectiveDate() {
return effectiveDate;
}
@@ -246,7 +197,7 @@ public class Catalog extends ValidatingConfig<Catalog> implements ICatalog {
public URI getCatalogURI() {
return catalogURI;
}
-
+
public PlanRules getPlanRules() {
return planRules;
}
@@ -256,12 +207,12 @@ public class Catalog extends ValidatingConfig<Catalog> implements ICatalog {
}
@Override
- public PlanPhase getPhaseFor(String name, Date date) {
- if(getEffectiveDate().getTime() >= date.getTime()){
- return getPhaseFromName(name);
- }
- return null;
- }
+ public PlanPhase getPhaseFor(String name, Date date) {
+ if(getEffectiveDate().getTime() >= date.getTime()){
+ return getPhaseFromName(name);
+ }
+ return null;
+ }
public void setPriceLists(PriceListSet priceLists) {
this.priceLists = priceLists;
@@ -274,7 +225,7 @@ public class Catalog extends ValidatingConfig<Catalog> implements ICatalog {
@Override
public void configureEffectiveDate(Date date) {
// Nothing to do here this is a method that is only inplemented on VersionedCatalog
-
+
}
public PriceList getPriceListFromName(String priceListName) {
@@ -286,7 +237,58 @@ public class Catalog extends ValidatingConfig<Catalog> implements ICatalog {
throws IllegalPlanChange {
return planRules.planChange(from, to, this);
}
+
+ @Override
+ public ValidationErrors validate(Catalog catalog, ValidationErrors errors) {
+ validate(catalog,errors, products);
+ validate(catalog,errors, plans);
+ priceLists.validate(catalog,errors);
+ planRules.validate(catalog, errors);
+ return errors;
+ }
+
+ private Collection<? extends ValidationError> validate(Catalog catalog,
+ ValidationErrors errors, ValidatingConfig<Catalog>[] configs) {
+ for(ValidatingConfig<Catalog> config: configs) {
+
+ }
+ return null;
+ }
- //TODO: MDW validation - only allow one default pricelist
+
+ @Override
+ public void initialize(Catalog catalog, URI sourceURI) {
+ catalogURI = sourceURI;
+ super.initialize(catalog, sourceURI);
+ planRules.initialize(catalog, sourceURI);
+ priceLists.initialize(catalog, sourceURI);
+ for(Product p : products) {
+ p.initialize(catalog, sourceURI);
+ }
+ for(Plan p : plans) {
+ p.initialize(catalog, sourceURI);
+ }
+ }
+
+
+ protected Catalog setProducts(Product[] products) {
+ this.products = products;
+ return this;
+ }
+ protected Catalog setSupportedCurrencies(Currency[] supportedCurrencies) {
+ this.supportedCurrencies = supportedCurrencies;
+ return this;
+ }
+
+ protected Catalog setPlanChangeRules(PlanRules planChangeRules) {
+ this.planRules = planChangeRules;
+ return this;
+ }
+
+ protected Catalog setPlans(Plan[] plans) {
+ this.plans = plans;
+ return this;
+ }
+
}
diff --git a/catalog/src/main/java/com/ning/billing/catalog/InternationalPrice.java b/catalog/src/main/java/com/ning/billing/catalog/InternationalPrice.java
index 4a64900..26960b5 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/InternationalPrice.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/InternationalPrice.java
@@ -32,13 +32,12 @@ import com.ning.billing.util.config.ValidationErrors;
@XmlAccessorType(XmlAccessType.NONE)
public class InternationalPrice extends ValidatingConfig<Catalog> implements IInternationalPrice {
-
private static Price[] zeroPrice;
//TODO MDW Validation - effectiveDateForExistingSubscriptons > catalog effectiveDate
@XmlElement(required=false)
private Date effectiveDateForExistingSubscriptons;
-
+
//TODO: Must have a price point for every configured currency
//TODO: No prices is a zero cost plan
@XmlElement(name="price")
@@ -64,7 +63,7 @@ public class InternationalPrice extends ValidatingConfig<Catalog> implements IIn
/* (non-Javadoc)
* @see com.ning.billing.catalog.IInternationalPrice#getPrice(com.ning.billing.catalog.api.Currency)
*/
- @Override
+ @Override
public BigDecimal getPrice(Currency currency) {
// Note if there are no prices specified we default to 0 for any currency
for(IPrice p : prices) {
@@ -85,31 +84,9 @@ public class InternationalPrice extends ValidatingConfig<Catalog> implements IIn
this.prices = prices;
return this;
}
-
@Override
- public void initialize(Catalog root, URI uri) {
- if(prices == null) {
- prices = getZeroPrice(root);
- }
- super.initialize(root, uri);
- }
-
- private synchronized Price[] getZeroPrice(Catalog root) {
- if(zeroPrice == null) {
- Currency[] currencies = root.getSupportedCurrencies();
- zeroPrice = new Price[currencies.length];
- for(int i = 0; i < currencies.length; i++) {
- prices[i] = new Price();
- prices[i].setCurrency(currencies[i]);
- prices[i].setValue(new BigDecimal(0));
- }
- }
- return zeroPrice;
- }
-
- @Override
public ValidationErrors validate(Catalog catalog, ValidationErrors errors) {
if(prices.length == 0) return errors;
Currency[] supportedCurrencies = catalog.getSupportedCurrencies();
@@ -130,8 +107,27 @@ public class InternationalPrice extends ValidatingConfig<Catalog> implements IIn
}
return false;
}
-
+ @Override
+ public void initialize(Catalog root, URI uri) {
+ if(prices == null) {
+ prices = getZeroPrice(root);
+ }
+ super.initialize(root, uri);
+ }
+
+ private synchronized Price[] getZeroPrice(Catalog root) {
+ if(zeroPrice == null) {
+ Currency[] currencies = root.getSupportedCurrencies();
+ zeroPrice = new Price[currencies.length];
+ for(int i = 0; i < currencies.length; i++) {
+ zeroPrice[i] = new Price();
+ zeroPrice[i].setCurrency(currencies[i]);
+ zeroPrice[i].setValue(new BigDecimal(0));
+ }
+ }
+ return zeroPrice;
+ }
}
diff --git a/catalog/src/main/java/com/ning/billing/catalog/io/VersionedCatalogLoader.java b/catalog/src/main/java/com/ning/billing/catalog/io/VersionedCatalogLoader.java
index 2085567..9c1aaf9 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/io/VersionedCatalogLoader.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/io/VersionedCatalogLoader.java
@@ -23,10 +23,16 @@ import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
+import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashSet;
import java.util.List;
import java.util.Scanner;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
import javax.xml.bind.JAXBException;
import javax.xml.transform.TransformerException;
@@ -60,35 +66,32 @@ public class VersionedCatalogLoader implements ICatalogLoader {
@Override
public VersionedCatalog load(String urlString) throws ServiceException{
try {
- return load(new URL(urlString));
+ List<URL> xmlURLs = null;
+
+ if(urlString.endsWith(XML_EXTENSION)) { //assume its an xml file
+ xmlURLs = new ArrayList<URL>();
+ xmlURLs.add(new URL(urlString));
+ } else { //assume its a directory
+ String[] directoryContents = getResourceListing(urlString);
+ xmlURLs = findXmlReferences(directoryContents, url);
+ }
+
+ VersionedCatalog result = new VersionedCatalog();
+ for(URL u : xmlURLs) {
+ Catalog catalog = XMLLoader.getObjectFromURL(u, Catalog.class);
+ result.add(catalog);
+ }
+ Date now = clock.getUTCNow().toDate();
+ result.configureEffectiveDate(now);
+ return result;
} catch (Exception e) {
throw new ServiceException("Problem encountered loading catalog", e);
}
}
- public VersionedCatalog load(URL url) throws IOException, SAXException, InvalidConfigException, JAXBException, TransformerException, URISyntaxException {
- List<URL> xmlURLs = null;
-
- if(url.getPath().endsWith(XML_EXTENSION)) { //assume its an xml file
- xmlURLs = new ArrayList<URL>();
- xmlURLs.add(url);
- } else { //assume its a directory
- String directoryContents = pullContentsFrom(url);
- xmlURLs = findXmlReferences(directoryContents, url);
- }
-
- VersionedCatalog result = new VersionedCatalog();
- for(URL u : xmlURLs) {
- Catalog catalog = XMLLoader.getObjectFromURL(u, Catalog.class);
- result.add(catalog);
- }
- Date now = clock.getUTCNow().toDate();
- result.configureEffectiveDate(now);
- return result;
- }
protected List<URL> findXmlReferences(String directoryContents, URL url) throws MalformedURLException {
- if(url.getProtocol().equals("file")) {
+ if(url.getProtocol().equals(PROTOCOL_FOR_FILE)) {
return findXmlFileReferences(directoryContents, url);
}
return findXmlUrlReferences(directoryContents, url);
@@ -163,4 +166,46 @@ public class VersionedCatalogLoader implements ICatalogLoader {
InputStream content = connection.getInputStream();
return new Scanner(content).useDelimiter("\\A").next();
}
+//
+// private String[] getResourceListing(String path) throws URISyntaxException, IOException {
+// URL dirURL = this.getClass().getClassLoader().getResource(path);
+// if (dirURL != null && dirURL.getProtocol().equals("file")) {
+// /* A file path: easy enough */
+// return new File(dirURL.toURI()).list();
+// }
+//
+// if (dirURL == null) {
+// /*
+// * In case of a jar file, we can't actually find a directory.
+// * Have to assume the same jar as clazz.
+// */
+// String me = clazz.getName().replace(".", "/")+".class";
+// dirURL = clazz.getClassLoader().getResource(me);
+// }
+//
+// if (dirURL.getProtocol().equals("jar")) {
+// /* A JAR path */
+// String jarPath = dirURL.getPath().substring(5, dirURL.getPath().indexOf("!")); //strip out only the JAR file
+// JarFile jar = new JarFile(URLDecoder.decode(jarPath, "UTF-8"));
+// Enumeration<JarEntry> entries = jar.entries(); //gives ALL entries in jar
+// Set<String> result = new HashSet<String>(); //avoid duplicates in case it is a subdirectory
+// while(entries.hasMoreElements()) {
+// String name = entries.nextElement().getName();
+// if (name.startsWith(path)) { //filter according to the path
+// String entry = name.substring(path.length());
+// int checkSubdir = entry.indexOf("/");
+// if (checkSubdir >= 0) {
+// // if it is a subdirectory, we just return the directory name
+// entry = entry.substring(0, checkSubdir);
+// }
+// result.add(entry);
+// }
+// }
+// return result.toArray(new String[result.size()]);
+// }
+//
+// throw new UnsupportedOperationException("Cannot list files for URL "+dirURL);
+// }
+
+
}
diff --git a/catalog/src/main/java/com/ning/billing/catalog/Price.java b/catalog/src/main/java/com/ning/billing/catalog/Price.java
index 369b9ac..cdbf464 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/Price.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/Price.java
@@ -51,7 +51,7 @@ public class Price extends ValidatingConfig<Catalog> implements IPrice {
return value;
}
- public Price setCurrency(Currency currency) {
+ protected Price setCurrency(Currency currency) {
this.currency = currency;
return this;
}
diff --git a/catalog/src/test/java/com/ning/billing/catalog/TestInternationalPrice.java b/catalog/src/test/java/com/ning/billing/catalog/TestInternationalPrice.java
new file mode 100644
index 0000000..a02541d
--- /dev/null
+++ b/catalog/src/test/java/com/ning/billing/catalog/TestInternationalPrice.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning licenses this file to you 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.ning.billing.catalog;
+
+import java.math.BigDecimal;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.catalog.api.Currency;
+
+public class TestInternationalPrice {
+ @Test
+ public void testZeroValue() throws URISyntaxException {
+ Catalog c = new MockCatalog();
+ c.setSupportedCurrencies(new Currency[]{Currency.GBP, Currency.EUR, Currency.USD, Currency.BRL, Currency.MXN});
+ InternationalPrice p0 = new MockInternationalPrice();
+ p0.setPrices(null);
+ p0.initialize(c, new URI("foo:bar"));
+ InternationalPrice p1 = new MockInternationalPrice();
+ p1.setPrices(new Price[] {
+ new Price().setCurrency(Currency.GBP).setValue(new BigDecimal(1)),
+ new Price().setCurrency(Currency.EUR).setValue(new BigDecimal(1)),
+ new Price().setCurrency(Currency.USD).setValue(new BigDecimal(1)),
+ new Price().setCurrency(Currency.BRL).setValue(new BigDecimal(1)),
+ new Price().setCurrency(Currency.MXN).setValue(new BigDecimal(1)),
+ });
+ p1.initialize(c, new URI("foo:bar"));
+
+ Assert.assertEquals(p0.getPrice(Currency.GBP), new BigDecimal(0));
+ Assert.assertEquals(p0.getPrice(Currency.EUR), new BigDecimal(0));
+ Assert.assertEquals(p0.getPrice(Currency.USD), new BigDecimal(0));
+ Assert.assertEquals(p0.getPrice(Currency.BRL), new BigDecimal(0));
+ Assert.assertEquals(p0.getPrice(Currency.MXN), new BigDecimal(0));
+
+ Assert.assertEquals(p1.getPrice(Currency.GBP), new BigDecimal(1));
+ Assert.assertEquals(p1.getPrice(Currency.EUR), new BigDecimal(1));
+ Assert.assertEquals(p1.getPrice(Currency.USD), new BigDecimal(1));
+ Assert.assertEquals(p1.getPrice(Currency.BRL), new BigDecimal(1));
+ Assert.assertEquals(p1.getPrice(Currency.MXN), new BigDecimal(1));
+
+ }
+}