killbill-memoizeit
Changes
catalog/src/test/resources/SpyCarAdvanced.xml 161(+154 -7)
Details
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/CatalogEntityCollection.java b/catalog/src/main/java/org/killbill/billing/catalog/CatalogEntityCollection.java
index b9bad42..d2d2cbd 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/CatalogEntityCollection.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/CatalogEntityCollection.java
@@ -42,7 +42,7 @@ public class CatalogEntityCollection<T extends CatalogEntity> implements Collect
}
- public CatalogEntityCollection(final Collection<T> entities) {
+ public CatalogEntityCollection(final Iterable<T> entities) {
this.data = new TreeMap<String, T>(Ordering.<String>natural());
for (final T cur : entities) {
addEntry(cur);
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultPlan.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultPlan.java
index b99ec4b..19ceed6 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultPlan.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultPlan.java
@@ -185,7 +185,7 @@ public class DefaultPlan extends ValidatingConfig<StandaloneCatalog> implements
p.initialize(catalog, sourceURI);
}
}
- this.priceListName = findPriceListForPlan(catalog);
+ this.priceListName = this.priceListName != null ? this.priceListName : findPriceListForPlan(catalog);
}
@Override
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultPriceList.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultPriceList.java
index 7335354..9bdf070 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultPriceList.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultPriceList.java
@@ -102,7 +102,7 @@ public class DefaultPriceList extends ValidatingConfig<StandaloneCatalog> implem
return this;
}
- public DefaultPriceList setPlans(final Collection<Plan> plans) {
+ public DefaultPriceList setPlans(final Iterable<Plan> plans) {
this.plans = new CatalogEntityCollection(plans);
return this;
}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/plugin/StandaloneCatalogMapper.java b/catalog/src/main/java/org/killbill/billing/catalog/plugin/StandaloneCatalogMapper.java
index 7c90442..6f52dc1 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/plugin/StandaloneCatalogMapper.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/plugin/StandaloneCatalogMapper.java
@@ -21,7 +21,8 @@ import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.List;
+import java.util.HashMap;
+import java.util.Map;
import javax.annotation.Nullable;
@@ -37,7 +38,6 @@ import org.killbill.billing.catalog.DefaultProduct;
import org.killbill.billing.catalog.DefaultRecurring;
import org.killbill.billing.catalog.DefaultUnit;
import org.killbill.billing.catalog.DefaultUsage;
-import org.killbill.billing.catalog.PriceListDefault;
import org.killbill.billing.catalog.StandaloneCatalog;
import org.killbill.billing.catalog.api.BillingMode;
import org.killbill.billing.catalog.api.CurrencyValueNull;
@@ -83,18 +83,22 @@ public class StandaloneCatalogMapper {
private final String catalogName;
private final BillingMode recurringBillingMode;
- private Collection<Product> tmpDefaultProducts;
- private Collection<Plan> tmpDefaultPlans;
+ private Iterable<Product> tmpDefaultProducts;
+ private Iterable<Plan> tmpDefaultPlans;
private DefaultPriceListSet tmpDefaultPriceListSet;
+ private Map<String, DefaultPriceList> tmpDefaultPriceListMap;
public StandaloneCatalogMapper(final String catalogName, final BillingMode recurringBillingMode) {
this.catalogName = catalogName;
this.recurringBillingMode = recurringBillingMode;
this.tmpDefaultProducts = null;
this.tmpDefaultPlans = null;
+ this.tmpDefaultPriceListMap = new HashMap<String, DefaultPriceList>();
}
public StandaloneCatalog toStandaloneCatalog(final StandalonePluginCatalog pluginCatalog, @Nullable URI catalogURI) {
+
+
final StandaloneCatalog result = new StandaloneCatalog();
result.setCatalogName(catalogName);
result.setEffectiveDate(pluginCatalog.getEffectiveDate().toDate());
@@ -105,12 +109,11 @@ public class StandaloneCatalogMapper {
result.setSupportedCurrencies(toArray(pluginCatalog.getCurrencies()));
result.setUnits(toDefaultUnits(pluginCatalog.getUnits()));
result.setPlanRules(toDefaultPlanRules(pluginCatalog.getPlanRules()));
-
for (final Product cur : pluginCatalog.getProducts()) {
for (Product target : result.getCurrentProducts()) {
if (target.getName().equals(cur.getName())) {
- ((DefaultProduct) target).setAvailable(toFilteredDefaultProduct(ImmutableList.copyOf(cur.getAvailable())));
- ((DefaultProduct) target).setIncluded(toFilteredDefaultProduct(ImmutableList.copyOf(cur.getIncluded())));
+ ((DefaultProduct) target).setAvailable(toFilteredDefaultProduct(cur.getAvailable()));
+ ((DefaultProduct) target).setIncluded(toFilteredDefaultProduct(cur.getIncluded()));
break;
}
}
@@ -252,7 +255,7 @@ public class StandaloneCatalogMapper {
}
- private Collection<Product> toDefaultProducts(final Iterable<Product> input) {
+ private Iterable<Product> toDefaultProducts(final Iterable<Product> input) {
if (tmpDefaultProducts == null) {
final Function<Product, Product> productTransformer = new Function<Product, Product>() {
@Override
@@ -260,22 +263,22 @@ public class StandaloneCatalogMapper {
return toDefaultProduct(input);
}
};
- tmpDefaultProducts = ImmutableList.<Product>copyOf(Iterables.transform(input, productTransformer));
+ tmpDefaultProducts = ImmutableList.copyOf(Iterables.transform(input, productTransformer));
}
return tmpDefaultProducts;
}
- private Collection<Product> toFilteredDefaultProduct(final Iterable<Product> input) {
+ private Collection<Product> toFilteredDefaultProduct(final Collection<Product> input) {
if (!input.iterator().hasNext()) {
return Collections.emptyList();
}
- final List<String> inputProductNames = ImmutableList.copyOf(Iterables.transform(input, new Function<Product, String>() {
+ final Iterable<String> inputProductNames = Iterables.transform(input, new Function<Product, String>() {
@Override
public String apply(final Product input) {
return input.getName();
}
- }));
- final Collection<Product> filteredAndOrdered = new ArrayList<Product>(inputProductNames.size());
+ });
+ final Collection<Product> filteredAndOrdered = new ArrayList<Product>(input.size());
for (final String cur : inputProductNames) {
final Product found = findOrIllegalState(tmpDefaultProducts, new Predicate<Product>() {
@Override
@@ -288,7 +291,7 @@ public class StandaloneCatalogMapper {
return filteredAndOrdered;
}
- private Collection<Plan> toDefaultPlans(final Iterable<Plan> input) {
+ private Iterable<Plan> toDefaultPlans(final Iterable<Plan> input) {
if (tmpDefaultPlans == null) {
final Function<Plan, Plan> planTransformer = new Function<Plan, Plan>() {
@Override
@@ -296,37 +299,26 @@ public class StandaloneCatalogMapper {
return toDefaultPlan(input);
}
};
- tmpDefaultPlans = ImmutableList.<Plan>copyOf(Iterables.transform(input, planTransformer));
+ tmpDefaultPlans = ImmutableList.copyOf(Iterables.transform(input, planTransformer));
}
return tmpDefaultPlans;
}
- private Collection<Plan> toFilterDefaultPlans(final Iterable<Plan> input) {
+ private Iterable<Plan> toFilterDefaultPlans(final String priceListName) {
if (tmpDefaultPlans == null) {
throw new IllegalStateException("Cannot filter on uninitialized plans");
}
- final List<String> inputPlanNames = ImmutableList.copyOf(Iterables.transform(input, new Function<Plan, String>() {
+ return Iterables.filter(tmpDefaultPlans, new Predicate<Plan>() {
@Override
- public String apply(final Plan input) {
- return input.getName();
+ public boolean apply(final Plan input) {
+ return input.getPriceListName().equals(priceListName);
}
- }));
- final List<Plan> filteredAndOrdered = new ArrayList<Plan>(inputPlanNames.size());
- for (final String cur : inputPlanNames) {
- final Plan found = findOrIllegalState(tmpDefaultPlans, new Predicate<Plan>() {
- @Override
- public boolean apply(final Plan inputPredicate) {
- return inputPredicate.getName().equals(cur);
- }
- }, "Failed to find plan " + cur);
- filteredAndOrdered.add(found);
- }
- return filteredAndOrdered;
+ });
}
private DefaultPriceListSet toDefaultPriceListSet(final PriceList defaultPriceList, final Iterable<PriceList> childrenPriceLists) {
if (tmpDefaultPriceListSet == null) {
- tmpDefaultPriceListSet = new DefaultPriceListSet(toPriceListDefault(defaultPriceList), toDefaultPriceLists(childrenPriceLists));
+ tmpDefaultPriceListSet = new DefaultPriceListSet(toDefaultPriceList(defaultPriceList), toDefaultPriceLists(childrenPriceLists));
}
return tmpDefaultPriceListSet;
}
@@ -381,22 +373,18 @@ public class StandaloneCatalogMapper {
if (input == null) {
return null;
}
- final DefaultPriceList result = new DefaultPriceList();
- result.setName(input.getName());
- result.setPlans(toFilterDefaultPlans(ImmutableList.copyOf(input.getPlans())));
- return result;
- }
- private PriceListDefault toPriceListDefault(@Nullable final PriceList input) {
- if (input == null) {
- return null;
+ DefaultPriceList result = tmpDefaultPriceListMap.get(input.getName());
+ if (result == null) {
+ result = new DefaultPriceList();
+ result.setName(input.getName());
+ result.setPlans(toFilterDefaultPlans(input.getName()));
+ tmpDefaultPriceListMap.put(input.getName(), result);
}
- final PriceListDefault result = new PriceListDefault();
- result.setName(input.getName());
- result.setPlans(toFilterDefaultPlans(ImmutableList.copyOf(input.getPlans())));
return result;
}
+
private Product toDefaultProduct(@Nullable final Product input) {
if (input == null) {
return null;
@@ -434,6 +422,7 @@ public class StandaloneCatalogMapper {
result.setInitialPhases(toDefaultPlanPhases(ImmutableList.copyOf(input.getInitialPhases())));
result.setPlansAllowedInBundle(input.getPlansAllowedInBundle());
result.setProduct(toDefaultProduct(input.getProduct()));
+ result.setPriceListName(input.getPriceListName());
return result;
}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/StandaloneCatalog.java b/catalog/src/main/java/org/killbill/billing/catalog/StandaloneCatalog.java
index 0511e71..e6e6cf1 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/StandaloneCatalog.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/StandaloneCatalog.java
@@ -323,7 +323,7 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
return phase.compliesWithLimits(unit, value);
}
- public StandaloneCatalog setProducts(final Collection<Product> products) {
+ public StandaloneCatalog setProducts(final Iterable<Product> products) {
this.products = new CatalogEntityCollection<Product>(products);
return this;
}
@@ -333,7 +333,7 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
return this;
}
- public StandaloneCatalog setPlans(final Collection<Plan> plans) {
+ public StandaloneCatalog setPlans(final Iterable<Plan> plans) {
this.plans = new CatalogEntityCollection<Plan>(plans);
return this;
}
catalog/src/test/resources/SpyCarAdvanced.xml 161(+154 -7)
diff --git a/catalog/src/test/resources/SpyCarAdvanced.xml b/catalog/src/test/resources/SpyCarAdvanced.xml
index f02a9cd..a08c425 100644
--- a/catalog/src/test/resources/SpyCarAdvanced.xml
+++ b/catalog/src/test/resources/SpyCarAdvanced.xml
@@ -458,6 +458,82 @@
</recurring>
</finalPhase>
</plan>
+ <plan name="cia-standard-monthly">
+ <product>Standard</product>
+ <initialPhases>
+ <phase type="TRIAL">
+ <duration>
+ <unit>DAYS</unit>
+ <number>30</number>
+ </duration>
+ <fixed>
+ <fixedPrice> <!-- empty price implies $0 -->
+ </fixedPrice>
+ </fixed>
+ </phase>
+ <phase type="DISCOUNT">
+ <duration>
+ <unit>MONTHS</unit>
+ <number>3</number>
+ </duration>
+ <recurring>
+ <billingPeriod>MONTHLY</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>GBP</currency>
+ <value>25.00</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>30.00</value>
+ </price>
+ <price>
+ <currency>USD</currency>
+ <value>33.00</value>
+ </price>
+ <price>
+ <currency>JPY</currency>
+ <value>3.30</value>
+ </price>
+ <price>
+ <currency>BTC</currency>
+ <value>0.04</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </phase>
+ </initialPhases>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <recurring>
+ <billingPeriod>MONTHLY</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>GBP</currency>
+ <value>50.00</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>75.00</value>
+ </price>
+ <price>
+ <currency>USD</currency>
+ <value>90.00</value>
+ </price>
+ <price>
+ <currency>JPY</currency>
+ <value>8.00</value>
+ </price>
+ <price>
+ <currency>BTC</currency>
+ <value>0.08</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </finalPhase>
+ </plan>
<plan name="discount-sports-monthly">
<product>Sports</product>
<initialPhases>
@@ -534,6 +610,82 @@
</recurring>
</finalPhase>
</plan>
+ <plan name="cia-sports-monthly">
+ <product>Sports</product>
+ <initialPhases>
+ <phase type="TRIAL">
+ <duration>
+ <unit>DAYS</unit>
+ <number>30</number>
+ </duration>
+ <fixed>
+ <fixedPrice> <!-- empty price implies $0 -->
+ </fixedPrice>
+ </fixed>
+ </phase>
+ <phase type="DISCOUNT">
+ <duration>
+ <unit>MONTHS</unit>
+ <number>3</number>
+ </duration>
+ <recurring>
+ <billingPeriod>MONTHLY</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>GBP</currency>
+ <value>150.00</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>150.00</value>
+ </price>
+ <price>
+ <currency>USD</currency>
+ <value>250.00</value>
+ </price>
+ <price>
+ <currency>JPY</currency>
+ <value>20.30</value>
+ </price>
+ <price>
+ <currency>BTC</currency>
+ <value>0.2</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </phase>
+ </initialPhases>
+ <finalPhase type="EVERGREEN">
+ <duration>
+ <unit>UNLIMITED</unit>
+ </duration>
+ <recurring>
+ <billingPeriod>MONTHLY</billingPeriod>
+ <recurringPrice>
+ <price>
+ <currency>GBP</currency>
+ <value>300.00</value>
+ </price>
+ <price>
+ <currency>EUR</currency>
+ <value>375.00</value>
+ </price>
+ <price>
+ <currency>USD</currency>
+ <value>450.00</value>
+ </price>
+ <price>
+ <currency>JPY</currency>
+ <value>40.00</value>
+ </price>
+ <price>
+ <currency>BTC</currency>
+ <value>0.4</value>
+ </price>
+ </recurringPrice>
+ </recurring>
+ </finalPhase>
+ </plan>
<plan name="discount-super-monthly">
<product>Super</product>
<initialPhases>
@@ -807,17 +959,12 @@
<plan>discount-standard-monthly</plan>
<plan>discount-sports-monthly</plan>
<plan>discount-super-monthly</plan>
- <plan>remotecontrol-monthly</plan>
- <plan>oilslick-monthly</plan>
</plans>
</childPriceList>
<childPriceList name="CIA">
<plans>
- <plan>discount-standard-monthly</plan>
- <plan>discount-sports-monthly</plan>
- <plan>discount-super-monthly</plan>
- <plan>remotecontrol-monthly</plan>
- <plan>oilslick-monthly</plan>
+ <plan>cia-standard-monthly</plan>
+ <plan>cia-sports-monthly</plan>
</plans>
</childPriceList>
</priceLists>