/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF 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 org.apache.openjpa.sdo;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.lib.conf.Configuration;
import org.apache.openjpa.lib.meta.ClassArgParser;
import org.apache.openjpa.persistence.PersistenceMetaDataFactory;

import commonj.sdo.Type;

/**
 * A specialized MetaDataFactory to process XML Schema based SDO MetaModel.
 * <br>
 * Caches bi-directional maps of SDO Type and Java Class.
 * <br>
  * Uses a {@link SDOTypeParser parser} to find SDO Types defined in *.xsd XML
 * Schema Definition resources. These resources are specified via configuration
 * as<br>
 * <pre>
 * &lt;property name="openjpa.MetaDataFactory" value="sdo(Resources=my.xsd"/&gt;
 * </pre>
 * and resolved against the thread context's classloader.
 *
 * @author Pinaki Poddar
 * @since 0.1.0
 */
public class SDOMetaDataFactory extends PersistenceMetaDataFactory {
	private OpenJPAConfiguration conf;
	private String resources;
	private List<String> resourceList;
	private SDOTypeParser sdoTypeParser;
	private Set<String> _typeNames = new HashSet<String>();
	private SDOMappingRepository repos;
	
	@Override
	public void setConfiguration(Configuration conf) {
		super.setConfiguration(conf);
		this.conf = (OpenJPAConfiguration)conf;
		repos = new SDOMappingRepository(this.conf);
	}
	
	public SDOMappingRepository getSDOMappingRepository() {
		return repos;
	}
	
	@Override
	public ClassArgParser newClassArgParser() {
		return getSDOTypeParser();
	}
	
	public SDOTypeParser getSDOTypeParser() {
		if (sdoTypeParser == null) {
			sdoTypeParser = new SDOTypeParser(conf);
		}
		return sdoTypeParser;
	}
		
	public void setResources(String resources) {
		this.resources = resources;
	}
	
	public String getResources() {
		return resources;
	}
	
	public String getGeneratedClassDirectory() {
		return "";
	}
	
	public void setGeneratedClassDirectory(String dir) {
		repos.setRootDirectory(dir);
	}

	
	@Override
	public void endConfiguration() {
		if (resources == null || resources.trim().length()==0)
			return;
		resourceList = new ArrayList<String>();
		String[] tokens = resources.split(";");
		for (String token:tokens) {
			resourceList.add(token);
		}
	}
	
	/**
	 * Get the fully-qualified, persistent Java class names.
	 * Invokes the parser for parsing XML Schema Definitions. 
	 * The parsed SDO types are then resolved to Java classes by the Mapping
	 * Repository, before returning from this method. 
	 */
	@Override
    public Set getPersistentTypeNames(boolean devpath, ClassLoader envLoader) {
    	if (resourceList == null || resourceList.isEmpty()) 
    		return _typeNames;
    	SDOTypeParser parser = getSDOTypeParser();
    	List<String> tmpList = new ArrayList<String>(resourceList);
    	resourceList.clear();
    	for (String resource:tmpList) {
    		List<Type> types = parser.parseXSDResource(resource);
    		for (Type type:types) {
    			Class c = repos.getJavaClass(type, true);//(type, envLoader);
    			_typeNames.add(c.getName());
    		}
    	}
    	return _typeNames;
    }
}
