/**
 * == @Spearal ==>
 * 
 * Copyright (C) 2014 Franck WOLFF & William DRAI (http://www.spearal.io)
 *
 * 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 org.spearal.jpa2.descriptor;

import java.util.Set;

import javax.persistence.Persistence;
import javax.persistence.PersistenceUtil;

import org.spearal.SpearalContext;
import org.spearal.SpearalEncoder;
import org.spearal.configuration.EncoderBeanDescriptorFactory;
import org.spearal.configuration.PropertyFactory.Property;
import org.spearal.impl.util.ClassDescriptionUtil;

/**
 * @author Franck WOLFF
 * @author William DRAI
 */
public class EntityDescriptorFactory implements EncoderBeanDescriptorFactory {
	
	private final Set<Class<?>> entityClasses;
		
	private final PersistenceUtil persistenceUtil;
	
	public EntityDescriptorFactory(Set<Class<?>> entityClasses) {
		this.entityClasses = entityClasses;
		
		persistenceUtil = Persistence.getPersistenceUtil();
		if (persistenceUtil == null)
			throw new NullPointerException("Could not get PersistenceUtil");
	}
	
	public static class EntityDescriptor implements EncoderBeanDescriptor {
		
		private final String description;
		private final Property[] properties;
		
		public EntityDescriptor(String description, Property[] properties) {
			this.description = description;
			this.properties = properties;
		}

		@Override
		public String getDescription() {
			return description;
		}

		@Override
		public Property[] getProperties() {
			return properties;
		}

		@Override
		public boolean isCacheable() {
			return false;
		}
	}
	
	@Override
	public EncoderBeanDescriptor createDescription(SpearalEncoder encoder, Object value) {
		Class<?> type = value.getClass();
		if (!entityClasses.contains(type))
			return null;
		
		SpearalContext context = encoder.getContext();
		Property[] properties = encoder.getPropertyFilter().get(type);
		boolean cloned = false;
		for (int i = 0; i < properties.length; i++) {
			if (properties[i] == null)
				continue;
			
			try {
				Object propertyValue = properties[i].get(value);
				if (!persistenceUtil.isLoaded(propertyValue)) {
					if (!cloned) {
						properties = properties.clone();
						cloned = true;
					}
					properties[i] = null;
				}
			}
			catch (Exception e) {
				throw new RuntimeException("Could not get property value for: " + properties[i], e);
			}			
		}
		
		String description = ClassDescriptionUtil.createAliasedDescription(context, type, properties);
		return new EntityDescriptor(description, properties);
	}
}

@@ -857,21 +857,28 @@
 .Spearal
-Encod
+PropertyFilt
 er;%0Aimpo
@@ -906,23 +906,24 @@
 uration.
-Encoder
+Filtered
 BeanDesc
@@ -1144,39 +1144,40 @@
 tory implements 
-Encoder
+Filtered
 BeanDescriptorFa
@@ -1594,23 +1594,24 @@
 lements 
-Encoder
+Filtered
 BeanDesc
@@ -2065,17 +2065,16 @@
 %0A%09%09%7D%0A%09%7D%0A
-%09
 %0A%09@Overr
@@ -2085,23 +2085,24 @@
 %09public 
-Encoder
+Filtered
 BeanDesc
@@ -2137,21 +2137,51 @@
 aral
-Encoder encod
+Context context, SpearalPropertyFilter filt
 er, 
@@ -2292,57 +2292,8 @@
 %0A%09%09%0A
-%09%09SpearalContext context = encoder.getContext();%0A
 %09%09Pr
@@ -2318,35 +2318,14 @@
 s = 
-encoder.getPropertyF
+f
 ilter
-()
 .get

Fix TextEntity test (SpearalConfigurator.init).