Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Copyright (C) 2013-2014 Sappenin Inc. (developers@sappenin.com) 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.sappenin.objectify.translate;
 
 import  com.google.appengine.api.datastore.EmbeddedEntity;
 
Factory for creating a JodaMoneyTranslator which can store component properties of a org.joda.money.BigMoneyProvider as a "value" and a "currencyUnit" (both of which are Strings), similar to how an Embedded class would be stored. The value is an encoded-String version of a java.math.BigDecimal that supports lexicographical sorting and large-digit number sets.

For more details, read this blog entry: "http://softwareblog.sappenin.com/2014/05/best-practices-for-storing-joda-money.html"

Author(s):
David Fuelling
 
 public class JodaMoneyEmbeddedEntityTranslatorFactory implements TranslatorFactory<BigMoneyProvider, EmbeddedEntity>
 {
 	public Translator create(final TypeKey tkfinal CreateContext ctxfinal Path path)
 	{
 
 		@SuppressWarnings("unchecked")
 		final Class<BigMoneyProviderclazz = (Class<BigMoneyProvider>) GenericTypeReflector.erase(tk.getTypeAsClass
 				());
 
 		if (org.joda.money.BigMoney.class.isAssignableFrom(clazz))
 		{
 			return new JodaMoneyTranslator(tkctxpathtrue);
 		}
 		else if (org.joda.money.Money.class.isAssignableFrom(clazz))
 		{
 			return new JodaMoneyTranslator(tkctxpathfalse);
 		}
 		else
 		{
 			return null;
 		}
 	}

Translator which knows what to do with a Joda org.joda.money.BigMoneyProvider, which is an interface implemented by both org.joda.money.BigMoney and org.joda.money.Money objects.

This class utilizes an optional com.sappenin.objectify.annotation.Money annotation which allows for fine-grained control over the field names used to store Money information, as well as indexing of each sub-field. See the Javadoc of that annotation for more details.

Author(s):
David Fuelling
 
 	static class JodaMoneyTranslator extends NullSafeTranslator<BigMoneyProvider, EmbeddedEntity>
 	{
 
 		// If false, use Money; Otherwise, use bigMoney
 		private boolean isBigMoney = false;
 
 		private String encodedAmountFieldName = "encodedAmount";
 
 		private String displayableAmountFieldName = "displayableAmount";
 
 		private String currencyCodeFieldName = "currencyCode";
 
 		private boolean storeDisplayableAmount;
 
 		private boolean indexDisplayableAmount;
		private boolean indexAmount;
		private boolean indexCurrencyCode;

Required Args Constructor.

Parameters:
tk
ctx
path
isBigMoney
		public JodaMoneyTranslator(final TypeKey tkfinal CreateContext ctxfinal Path path,
				final boolean isBigMoney)
		{
			Type componentType = GenericUtils.getMapValueType(tk.getType());
			 = ctx.getFactory().getTranslators().get(new TypeKey<>(componentTypetk), ctxpath);
			this. = isBigMoney;
			// Look for an @BigDecimal Annotation, if present.
			Money moneyAnnotation = TypeUtils.getAnnotation(tk.getAnnotations(), Money.class);
			if (moneyAnnotation != null)
			{
				 = moneyAnnotation.indexCurrencyCode();
				 = moneyAnnotation.indexEncodedAmount();
			}
		}
		protected BigMoneyProvider loadSafe(EmbeddedEntity nodeLoadContext ctxPath paththrows SkipException
		{
			BigMoneyProvider returnable = null;
			// Get the amount as a java.math.BigDecimal
			if (node.hasProperty())
			{
				BigDecimal bdValue = null;
				CurrencyUnit currencyUnit = .;
				// //////////
				// Populate bdValue (the BigDecimal Value)
				// //////////
				Object encodedAmountFieldValue = node.getProperty();
				if ((encodedAmountFieldValue != null) && (encodedAmountFieldValue.toString().length() > 0))
				{
					try
					{
						bdValue = BigDecimalCodec.decodeAsBigDecimal(encodedAmountFieldValue.toString());
					}
					catch (Exception e)
					{
						..print("Unable to Decode java.math.BigDecimal from encoded string \""
encodedAmountFieldValue + "\"");
					}
				}
				// //////////
				// Populate currencyUnit (the CurrencyUnit for the returnable
				// Money object)
				// //////////
				Object currencyCodeFieldValue = node.getProperty();
				if ((currencyCodeFieldValue != null) && (currencyCodeFieldValue.toString().length() > 0))
				{
					currencyUnit = CurrencyUnit.getInstance(currencyCodeFieldValue.toString());
				}
				// /////////////////
				// Populate the BigMoney with data from above.
				// /////////////////
				{
					returnable = BigMoney.of(currencyUnitbdValue);
				}
				else
				{
					returnable = org.joda.money.Money.of(currencyUnitbdValue);
				}
			}
			return returnable;
		}
		protected EmbeddedEntity saveSafe(BigMoneyProvider pojoboolean indexSaveContext ctxPath path)
		{
			if (pojo == null)
			{
				throw new SkipException();
			}
			else
			{
				EmbeddedEntity emb = new EmbeddedEntity();
				final BigMoney bigMoney = pojo.toBigMoney();
				// /////////////////////////
				// Handle the EncodedAmount Path
				// /////////////////////////
				// Encode the Amount value as a String
				{
					String encodedAmountValue = BigDecimalCodec.encode(bigMoney.getAmount());
					Path propPath = path.extend();
					Object value = .save(encodedAmountValuectxpropPath);
					DatastoreUtils.setContainerProperty(embvaluectx,
							propPath);
				}
				// /////////////////////////
				// Handle the CurrencyCode
				// /////////////////////////
				// Encode the Amount value as a String
				{
					String currencyCodeValue = bigMoney.getCurrencyUnit().getCurrencyCode();
					Path propPath = path.extend(this.);
							.save(currencyCodeValuethis.ctxpropPath);
					DatastoreUtils
									propPath);
				}
				// /////////////////////////
				// Handle the Displayable Amount
				// /////////////////////////
				{
					String displayableValue = bigMoney.toString();
					Path propPath = path.extend(this.);
							.save(displayableValuethis.ctxpropPath);
					DatastoreUtils.setContainerProperty(embthis.value,
							this.ctxpropPath);
				}
				return emb;
			}
		}
	}
New to GrepCode? Check out our FAQ X