package com.nec.webotx.webservice.sample;

import java.net.PasswordAuthentication;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.Set;

import javax.xml.registry.BulkResponse;
import javax.xml.registry.BusinessLifeCycleManager;
import javax.xml.registry.BusinessQueryManager;
import javax.xml.registry.Connection;
import javax.xml.registry.ConnectionFactory;
import javax.xml.registry.JAXRException;
import javax.xml.registry.RegistryService;
import javax.xml.registry.infomodel.Classification;
import javax.xml.registry.infomodel.ClassificationScheme;
import javax.xml.registry.infomodel.Concept;
import javax.xml.registry.infomodel.EmailAddress;
import javax.xml.registry.infomodel.ExternalIdentifier;
import javax.xml.registry.infomodel.ExternalLink;
import javax.xml.registry.infomodel.InternationalString;
import javax.xml.registry.infomodel.Organization;
import javax.xml.registry.infomodel.PersonName;
import javax.xml.registry.infomodel.PostalAddress;
import javax.xml.registry.infomodel.Service;
import javax.xml.registry.infomodel.ServiceBinding;
import javax.xml.registry.infomodel.SpecificationLink;
import javax.xml.registry.infomodel.TelephoneNumber;
import javax.xml.registry.infomodel.User;

public class JAXRPublishSample {
	Connection connection = null;
	public static void main(String[] args) {
		ResourceBundle bundle =
			ResourceBundle.getBundle(
				"com.nec.webotx.webservice.sample.JAXRSample");
		String queryURL = bundle.getString("query.url");
		String publishURL = bundle.getString("publish.url");
		String username = bundle.getString("registry.username");
		String password = bundle.getString("registry.password");

		JAXRPublishSample sample = new JAXRPublishSample();
		sample.makeConnection(queryURL, publishURL);
		sample.executePublish(username, password);
	}

	public void makeConnection(String queryURL, String publishURL) {
		ResourceBundle bundle =
			ResourceBundle.getBundle(
				"com.nec.webotx.webservice.sample.JAXRSample");
		String factoryClass = "com.sun.xml.registry.uddi.ConnectionFactoryImpl";
		Properties props = new Properties();
		props.setProperty("javax.xml.registry.queryManagerURL", queryURL);
		props.setProperty("javax.xml.registry.lifeCycleManagerURL", publishURL);
		props.setProperty("javax.xml.registry.factoryClass", factoryClass);
		
		String uuidString = bundle.getString("postal.uuidString");
		
		props.setProperty("javax.xml.registry.postalAddressScheme",
			uuidString);
		props.setProperty("javax.xml.registry.semanticEquivalences", 
			"urn:uuid:PostalAddressAttributes/StreetNumber," + 
			"urn:" + uuidString + "/MyStreetNumber|" +
			"urn:uuid:PostalAddressAttributes/City," + 
			"urn:" + uuidString + "/MyCity|" +
			"urn:uuid:PostalAddressAttributes/State," +                   
			"urn:" + uuidString + "/MyState|" +
			"urn:uuid:PostalAddressAttributes/Country," +
			"urn:" + uuidString + "/MyCountry");
			
		try {
			ConnectionFactory cf = ConnectionFactory.newInstance();
			cf.setProperties(props);
			connection = cf.createConnection();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void executePublish(String username, String password) {
		RegistryService rs = null;
		BusinessLifeCycleManager blcm = null;
		BusinessQueryManager bqm = null;
		ResourceBundle bundle =
			ResourceBundle.getBundle(
				"com.nec.webotx.webservice.sample.JAXRSample");

		try {
			rs = connection.getRegistryService();
			blcm = rs.getBusinessLifeCycleManager();
			bqm = rs.getBusinessQueryManager();
			//login
			PasswordAuthentication passwdAuth =
				new PasswordAuthentication(username, password.toCharArray());
			Set creds = new HashSet();
			creds.add(passwdAuth);
			connection.setCredentials(creds);

			//save Concept
			Concept specConcept =
				blcm.createConcept(null, bundle.getString("concept.name"), "");
			InternationalString is =
				blcm.createInternationalString(
					bundle.getString("concept.description"));
			specConcept.setDescription(is);
			ExternalLink wsdlLink =
				blcm.createExternalLink(
					bundle.getString("link.uri"),
					bundle.getString("link.description"));
			specConcept.addExternalLink(wsdlLink);

			String schemeName = "uddi-org:types";
			ClassificationScheme uddiOrgTypes =
				bqm.findClassificationSchemeByName(null, schemeName);

			Classification wsdlSpecClassification =
				blcm.createClassification(uddiOrgTypes, "wsdlSpec", "wsdlSpec");
			specConcept.addClassification(wsdlSpecClassification);

			Collection concepts = new ArrayList();
			concepts.add(specConcept);
			BulkResponse response = blcm.saveConcepts(concepts);

			Collection exceptions = response.getExceptions();
			javax.xml.registry.infomodel.Key concKey = null;
			String uuidString = null;
			if (exceptions == null) {
				Collection keys = response.getCollection();
				Iterator keyIter = keys.iterator();
				if (keyIter.hasNext()) {
					concKey = (javax.xml.registry.infomodel.Key) keyIter.next();
					uuidString = concKey.getId();
					System.out.println("save concept successful");
				}
			} else {
				Iterator excIter = exceptions.iterator();
				Exception exception = null;
				while (excIter.hasNext()) {
					exception = (Exception) excIter.next();
					System.err.println(
						"Exception on save: " + exception.toString());
				}
			}

			//save Organization
			Organization org =
				blcm.createOrganization(bundle.getString("org.name"));
			InternationalString s =
				blcm.createInternationalString(
					bundle.getString("org.description"));
			org.setDescription(s);

			User primaryContact = blcm.createUser();
			PersonName pName =
				blcm.createPersonName(bundle.getString("person.name"));
			primaryContact.setPersonName(pName);

			PostalAddress address =
				blcm.createPostalAddress(
					bundle.getString("postal.address1"),
					bundle.getString("postal.address2"),
					bundle.getString("postal.address3"),
					bundle.getString("postal.address4"),
					bundle.getString("postal.address5"),
					bundle.getString("postal.address6"),
					bundle.getString("postal.address7"));
			Collection postalAddresses = new ArrayList();
			postalAddresses.add(address);
			primaryContact.setPostalAddresses(postalAddresses);

			EmailAddress emailAddress =
				blcm.createEmailAddress(bundle.getString("email.address"));
			Collection emailAddresses = new ArrayList();
			emailAddresses.add(emailAddress);
			primaryContact.setEmailAddresses(emailAddresses);

			TelephoneNumber tNum = blcm.createTelephoneNumber();
			tNum.setNumber(bundle.getString("phone.number"));
			Collection phoneNums = new ArrayList();
			phoneNums.add(tNum);
			primaryContact.setTelephoneNumbers(phoneNums);

			org.setPrimaryContact(primaryContact);

			ClassificationScheme cScheme =
				blcm.createClassificationScheme(
					blcm.createInternationalString(
						bundle.getString("classification.scheme")),
					blcm.createInternationalString(""));
			javax.xml.registry.infomodel.Key cKey =
				(javax.xml.registry.infomodel.Key) blcm.createKey(
					bundle.getString("schema.key"));
			cScheme.setKey(cKey);
			Classification classification =
				blcm.createClassification(
					cScheme,
					bundle.getString("classification.name"),
					bundle.getString("classification.value"));
			org.addClassification(classification);

			ClassificationScheme cScheme1 =
				blcm.createClassificationScheme(
					blcm.createInternationalString(
						bundle.getString("classification.scheme1")),
					blcm.createInternationalString(""));
			javax.xml.registry.infomodel.Key cKey1 =
				(javax.xml.registry.infomodel.Key) blcm.createKey(
					bundle.getString("schema.key1"));
			cScheme1.setKey(cKey1);
			classification =
				blcm.createClassification(
					cScheme,
					bundle.getString("classification.name1"),
					bundle.getString("classification.value1"));
			org.addClassification(classification);

			ClassificationScheme cScheme2 =
				blcm.createClassificationScheme(
					blcm.createInternationalString(
						bundle.getString("classification.scheme2")),
					blcm.createInternationalString(""));
			javax.xml.registry.infomodel.Key cKey2 =
				(javax.xml.registry.infomodel.Key) blcm.createKey(
					bundle.getString("schema.key2"));
			cScheme2.setKey(cKey2);

			ExternalIdentifier ei =
				blcm.createExternalIdentifier(
					cScheme2,
					bundle.getString("classification.name2"),
					bundle.getString("classification.value2"));
			org.addExternalIdentifier(ei);

			Collection services = new ArrayList();
			Service service =
				blcm.createService(bundle.getString("service.name"));
			service.setDescription(
				blcm.createInternationalString(
					bundle.getString("service.description")));

			Collection serviceBindings = new ArrayList();
			ServiceBinding binding = blcm.createServiceBinding();
			binding.setValidateURI(false);
			binding.setAccessURI(bundle.getString("svcbinding.accessURI"));

			//Find Concept
			Collection namePatterns = new ArrayList();
			namePatterns.add(bundle.getString("concept.name"));
						
			BulkResponse br =
				bqm.findConcepts(null, namePatterns, null, null, null);
			Collection specConcepts = br.getCollection();

			Iterator iter = specConcepts.iterator();
			Concept retConcept = null;
			if (!iter.hasNext()) {
				System.out.println("No WSDL specification concepts found");
			} else {
				while (iter.hasNext()) {
					Concept testConcept = (Concept) iter.next();
					String testId = testConcept.getKey().getId();
					if (testId.equals(uuidString)) {
						retConcept = testConcept;
						System.out.println("find concept successful");
					}
					
				}
			}

			// If we found the concept, we can save the organization
			if (retConcept != null) {
				Collection links = retConcept.getExternalLinks();
				if (links.size() > 0) {
					ExternalLink link = (ExternalLink) links.iterator().next();
				}
				SpecificationLink specLink = blcm.createSpecificationLink();
				specLink.setSpecificationObject(retConcept);
				binding.addSpecificationLink(specLink);
			}
			serviceBindings.add(binding);
			service.addServiceBindings(serviceBindings);
			services.add(service);
			org.addServices(services);

			Collection orgs = new ArrayList();
			orgs.add(org);
			BulkResponse response2 = blcm.saveOrganizations(orgs);
			
			exceptions = response2.getExceptions();
			if (exceptions == null) {
				System.out.println("save organization successful");
			} else {
				Iterator excIter = exceptions.iterator();
				Exception exception = null;
				while (excIter.hasNext()) {
					exception = (Exception) excIter.next();
					System.err.println(exception.toString());
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (connection != null) {
				try {
					connection.close();
				} catch (JAXRException je) {
				}
			}
		}
	}
}
