/*******************************************************************************
 * Copyright (c) 2009, 2012 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * IBM Corporation - initial API and implementation
 * yyyymmdd bug      Email and other contact information
 * -------- -------- -----------------------------------------------------------
 * 20091021   291954 ericdp@ca.ibm.com - Eric D. Peters, JAX-RS: Implement JAX-RS Facet
 * 20091106   291954 ericdp@ca.ibm.com - Eric D. Peters, JAX-RS: Implement JAX-RS Facet
 * 20100302   304405 ericdp@ca.ibm.com - Eric D. Peters, JAX-RS Facet : support JAX-RS 1.1 (JSR 311)
 * 20100303   291954 kchong@ca.ibm.com - Keith Chong, JAX-RS: Implement JAX-RS Facet
 * 20100310   291954 ericdp@ca.ibm.com - Eric D. Peters, JAX-RS: Implement JAX-RS Facet
 * 20100324   306937 ericdp@ca.ibm.com - Eric D. Peters, JAX-RS Properties page- NPE after pressing OK
 * 20100413   307552 ericdp@ca.ibm.com - Eric D. Peters, JAX-RS and Java EE 6 setup is incorrect
 * 20100428   310905 ericdp@ca.ibm.com - Eric D. Peters, JAX-RS facet fails to install due to NPE or runtime exception due to duplicate cp entries
 * 20100519   313576 ericdp@ca.ibm.com - Eric D. Peters, JAX-RS tools- validation problems
 * 20100618   307059 ericdp@ca.ibm.com - Eric D. Peters, JAX-RS properties page- fields empty or incorrect
 * 20100820   323192 ericdp@ca.ibm.com - Eric D. Peters, JAX-RS- Not prompted to enter servlet class when adding JAX-RS facet to a new web project
 * 20101123   330916 ericdp@ca.ibm.com - Eric D. Peters, JAX-RS - facet install should consider Web project associated with multiple EARs
 * 20110822   349541 atosak@ca.ibm.com - Atosa Khoddamhazrati, JAX-RS Facet assumes a project has a runtime when enabling the facet
 * 20120206   365103 jenyoung@ca.ibm.com - Jennifer Young, JAX-RS configuration UI should have the Update Deployment descriptor check box available
 * 20120427   377916 jenyoung@ca.ibm.com - Jennifer Young, The JAX-RS install operation config should be updated whenever there are provider set changes
 *******************************************************************************/
package org.eclipse.jst.ws.jaxrs.ui.internal.project.facet;

import java.util.ArrayList;
import java.util.Iterator;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.dialogs.DialogSettings;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jst.common.project.facet.core.libprov.ILibraryProvider;
import org.eclipse.jst.common.project.facet.core.libprov.LibraryInstallDelegate;
import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderOperationConfig;
import org.eclipse.jst.common.project.facet.core.libprov.internal.LibraryProvider;
import org.eclipse.jst.common.project.facet.ui.libprov.LibraryProviderFrameworkUi;
import org.eclipse.jst.j2ee.project.EarUtilities;
import org.eclipse.jst.j2ee.project.WebUtilities;
import org.eclipse.jst.j2ee.project.facet.IJ2EEModuleFacetInstallDataModelProperties;
import org.eclipse.jst.server.core.FacetUtil;
import org.eclipse.jst.ws.jaxrs.core.internal.IJAXRSCoreConstants;
import org.eclipse.jst.ws.jaxrs.core.internal.jaxrslibraryproviderconfig.JAXRSLibraryProviderUtil;
import org.eclipse.jst.ws.jaxrs.core.internal.jaxrssharedlibraryconfig.SharedLibraryConfiguratorUtil;
import org.eclipse.jst.ws.jaxrs.core.internal.project.facet.IJAXRSFacetInstallDataModelProperties;
import org.eclipse.jst.ws.jaxrs.core.internal.project.facet.JAXRSSharedLibraryProviderInstallOperationConfig;
import org.eclipse.jst.ws.jaxrs.core.internal.project.facet.JAXRSUserLibraryProviderInstallOperationConfig;
import org.eclipse.jst.ws.jaxrs.ui.internal.IJAXRSUIConstants;
import org.eclipse.jst.ws.jaxrs.ui.internal.JAXRSUIPlugin;
import org.eclipse.jst.ws.jaxrs.ui.internal.Messages;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.wst.common.frameworks.datamodel.AbstractDataModelProvider;
import org.eclipse.wst.common.frameworks.datamodel.DataModelEvent;
import org.eclipse.wst.common.frameworks.datamodel.DataModelFactory;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
import org.eclipse.wst.common.frameworks.internal.datamodel.ui.DataModelWizardPage;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.IPreset;
import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
import org.eclipse.wst.common.project.facet.core.runtime.internal.BridgedRuntime;
import org.eclipse.wst.common.project.facet.ui.IFacetWizardPage;
import org.eclipse.wst.common.project.facet.ui.IWizardContext;
import org.eclipse.wst.server.core.IRuntime;
import org.eclipse.wst.server.core.IRuntimeType;

/**
 * JAXRS Facet installation wizard page.
 * 
 */
@SuppressWarnings("restriction")
public class JAXRSFacetInstallPage extends DataModelWizardPage implements IJAXRSFacetInstallDataModelProperties, IFacetWizardPage
{
  // UI
  private ServletInformationGroup servletInfoGroup;

  private IDialogSettings dialogSettings;
  private IDataModel webAppDataModel;
  private String sEARProject = null;
  private String sWEBProject = null;
  private IWizardContext context;
  private String sTargetRuntime = null;
  private IRuntime targetRuntime = null;
  private boolean bAddToEAR = false;
  private static final String SETTINGS_SERVLET = "servletName"; //$NON-NLS-1$
  private static final String SETTINGS_SERVLET_CLASSNAME = "servletClassname"; //$NON-NLS-1$
  private static final String SETTINGS_URL_MAPPINGS = "urlMappings"; //$NON-NLS-1$
  private static final String SETTINGS_URL_PATTERN = "pattern"; //$NON-NLS-1$
  private Button updateDDCheckBox;
  private Composite composite = null;
  private java.util.List<IProject> earProjects = null;
  private IPreset selectedPreset = null;
  private ILibraryProvider currentlySelectedLibraryType;
  private boolean isProjectCreationMode = true; // project creation = true,
                                                // add/remove facets mode =
                                                // false

  /**
   * Zero argument constructor
   */
  public JAXRSFacetInstallPage()
  {
    super(DataModelFactory.createDataModel(new AbstractDataModelProvider()
    {/*
      * do nothing
      */
    }), "jaxrs.facet.install.page"); //$NON-NLS-1$
    setTitle(Messages.JAXRSFacetInstallPage_title);
    setDescription(Messages.JAXRSFacetInstallPage_description);
    dialogSettings = JAXRSUIPlugin.getDefault().getDialogSettings();

  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * org.eclipse.wst.common.frameworks.internal.datamodel.ui.DataModelWizardPage
   * #createTopLevelComposite(org.eclipse.swt.widgets.Composite)
   */
  protected Composite createTopLevelComposite(final Composite parent)
  {
    initializeDialogUnits(parent);
    composite = new Composite(parent, SWT.NONE);
    final GridLayout jaxrsCompositeLayout = new GridLayout(1, false);
    jaxrsCompositeLayout.marginTop = 0;
    jaxrsCompositeLayout.marginBottom = 0;
    jaxrsCompositeLayout.marginRight = 0;
    jaxrsCompositeLayout.marginLeft = 0;
    composite.setLayout(jaxrsCompositeLayout);

    final LibraryInstallDelegate librariesInstallDelegate = (LibraryInstallDelegate) getDataModel().getProperty(LIBRARY_PROVIDER_DELEGATE);
    
    currentlySelectedLibraryType = librariesInstallDelegate == null ? null : librariesInstallDelegate.getLibraryProvider();
	librariesInstallDelegate.getLibraryProviders();
	java.util.List<ILibraryProvider> providers = librariesInstallDelegate.getLibraryProviders();
	if (providers != null) {
		for (ILibraryProvider provider : providers) {
			if (provider != null) {
				if (provider instanceof LibraryProvider) {
					if (!provider.isAbstract()) {
						LibraryProviderOperationConfig config = librariesInstallDelegate
								.getLibraryProviderOperationConfig(provider);

						if (config instanceof JAXRSUserLibraryProviderInstallOperationConfig) {
							JAXRSUserLibraryProviderInstallOperationConfig customConfig = (JAXRSUserLibraryProviderInstallOperationConfig) config;
							customConfig.setModel(getDataModel());
						} else if (config instanceof JAXRSSharedLibraryProviderInstallOperationConfig) {
							JAXRSSharedLibraryProviderInstallOperationConfig customConfig = (JAXRSSharedLibraryProviderInstallOperationConfig) config;
							customConfig.setModel(getDataModel());
						}
					}
				}
			}
		}
	}    

    final Control librariesComposite = LibraryProviderFrameworkUi.createInstallLibraryPanel(composite, librariesInstallDelegate, Messages.JAXRSFacetInstallPage_JAXRSImplementationLibrariesFrame);

    GridData gd = new GridData(GridData.FILL_HORIZONTAL);
    gd.horizontalSpan = 3;

    librariesComposite.setLayoutData(gd);
	updateDDCheckBox = new Button(composite, SWT.CHECK);
	updateDDCheckBox.setText(Messages.JAXRSFacetInstallPage_UpdateDD);
	updateDDCheckBox.addSelectionListener(
			new SelectionAdapter() {
				public void widgetSelected(final SelectionEvent event) { 
					servletInfoGroup.setFieldsEnabled(updateDDCheckBox.getSelection());
				}
				});


    servletInfoGroup = new ServletInformationGroup(composite, SWT.NONE);
    servletInfoGroup.setDataModel(model);
   	updateUpdateDDState(librariesInstallDelegate.getLibraryProvider().getId());
   	servletInfoGroup.setVisible(isWebFacetSelected());
    addModificationListeners();

    return composite;
  }

private void updateUpdateDDState(String libraryProviderID) {
	boolean bUserLibrary = libraryProviderID.equals(IJAXRSUIConstants.USER_LIBRARY_ID);
	boolean nOopLibrary = libraryProviderID.equals(IJAXRSCoreConstants.NO_OP_LIBRARY_ID);
	if (bUserLibrary || nOopLibrary) {
		updateDDCheckBox.setVisible(isJEE6orGreater());
	}  else if (!isWebFacetSelected() ) {
		updateDDCheckBox.setVisible(false);
	} else
		updateDDCheckBox.setVisible(showUpdateDDCheckBox(libraryProviderID));
    if (updateDDCheckBox.getVisible()) {
    		boolean selected;
    		if (!bUserLibrary && !nOopLibrary)
    			selected = getUpdateDDCheckBoxSelected(libraryProviderID);
    		else 
    			selected = true;
    		servletInfoGroup.setFieldsEnabled(selected);
    		updateDDCheckBox.setSelection(selected);
    		updateDDCheckBox.getSelection();
    }
	if (updateDDCheckBox.getVisible())
		model.setBooleanProperty(IJAXRSFacetInstallDataModelProperties.UPDATEDD, updateDDCheckBox.getSelection());
	else
		model.setBooleanProperty(IJAXRSFacetInstallDataModelProperties.UPDATEDD, isWebFacetSelected());
}

@SuppressWarnings("rawtypes")
private boolean isWebFacetSelected() {
	Iterator it = this.context.getSelectedProjectFacets().iterator();
	while (it.hasNext()) {
		// find Web facet
		IProjectFacetVersion pfv = (IProjectFacetVersion) it.next();
		if (pfv.getProjectFacet().getId().equals("jst.web")) { //$NON-NLS-1$
			return true;
		}
	}
	return false;

}

	@SuppressWarnings("rawtypes")
	private boolean isJEE6orGreater() {
		sWEBProject = this.context.getProjectName();
		Iterator it = this.context.getSelectedProjectFacets().iterator();
		IProjectFacetVersion webFacetVersion = null;
		while (it.hasNext()) {
			// find Web facet
			IProjectFacetVersion pfv = (IProjectFacetVersion) it.next();
			if (pfv.getProjectFacet().getId().equals("jst.web")) { //$NON-NLS-1$
				webFacetVersion = pfv;
				break;
			}
		}
		if (webFacetVersion != null) {
			if (webFacetVersion.equals(WebUtilities.DYNAMIC_WEB_30)) 
				return true;
				
		}

		return false;
	}

private boolean getUpdateDDCheckBoxSelected(String libraryProviderID) {
	return JAXRSLibraryProviderUtil.isUpdateDDCheckBoxSelectedByDefault(libraryProviderID);
}

private boolean showUpdateDDCheckBox(String libraryProviderID) {
	if (libraryProviderID.equals(IJAXRSUIConstants.USER_LIBRARY_ID))
		return true;
	return JAXRSLibraryProviderUtil.isUpdateDDCheckBoxSupportAvailable(libraryProviderID);
}

private void initializeValues()
  {
    IDialogSettings root = dialogSettings.getSection(IJAXRSUIConstants.SETTINGS_ROOT);

    if (!this.isProjectCreationMode)
    {
      // We are in add/remove facets mode
      IProject webProject = SharedLibraryConfiguratorUtil.getWebProject(model);
      if (webProject != null)
      {
        try
        {
          IFacetedProject fProject = ProjectFacetsManager.create(webProject);
          // Get the runtime associated with this project
          org.eclipse.wst.common.project.facet.core.runtime.IRuntime facetRuntime = fProject.getPrimaryRuntime();
          if (facetRuntime != null)
          {
            IRuntime runtime = FacetUtil.getRuntime(facetRuntime);
            if (runtime != null)
            {
              IRuntimeType rtType = runtime.getRuntimeType();
              if (rtType != null)
              {
                sTargetRuntime = rtType.getId();
              }
              // Now, set the property
              model.setStringProperty(IJAXRSFacetInstallDataModelProperties.TARGETRUNTIME, sTargetRuntime);
            }
          }
        }
        catch (CoreException e)
        {
          // We should have a faceted project
        }
      }
      String earName = model.getStringProperty(IJAXRSFacetInstallDataModelProperties.EARPROJECT_NAME);
      if (earName == null || earName.equals(""))
      {
        if (webProject != null)
        {

          IProject[] earProjects = EarUtilities.getReferencingEARProjects(webProject); // required
                                                                                       // org.eclipse.jem.util
          if (earProjects.length > 0)
          {
            earName = earProjects[0].getName();
            // Since we do have an EAR...
            this.bAddToEAR = true;
            this.sEARProject = earName;
            model.setBooleanProperty(IJAXRSFacetInstallDataModelProperties.ADD_TO_EAR, true);
            model.setStringProperty(IJAXRSFacetInstallDataModelProperties.EARPROJECT_NAME, earName);
          }
        }
      }
    }
    

			String servletName = null;
			if (root != null)
				servletName = root.get(SETTINGS_SERVLET);
			if (servletName == null || servletName.equals("")) { //$NON-NLS-1$
				servletName = (String) model
						.getDefaultProperty(IJAXRSFacetInstallDataModelProperties.SERVLET_NAME);
			}
			servletInfoGroup.txtJAXRSServletName.setText(servletName);

			String servletClassname = null;
			String libraryProviderID = "";
			LibraryInstallDelegate librariesInstallDelegate = (LibraryInstallDelegate) getDataModel()
					.getProperty(LIBRARY_PROVIDER_DELEGATE);
			if (librariesInstallDelegate != null
					&& librariesInstallDelegate.getLibraryProvider() != null)
				libraryProviderID = librariesInstallDelegate
						.getLibraryProvider().getId();
			if (root != null) {
				servletClassname = root.get(libraryProviderID
						+ SETTINGS_SERVLET_CLASSNAME);
			}
			if (servletClassname == null) {
				servletClassname = JAXRSLibraryProviderUtil
						.getServletClassName(libraryProviderID);
				if (servletClassname == null)
					servletClassname = (String) model
							.getDefaultProperty(IJAXRSFacetInstallDataModelProperties.SERVLET_CLASSNAME);
			}
			servletInfoGroup.txtJAXRSServletClassName.setText(servletClassname);

			loadURLMappingPatterns(root);
  }

  private void saveSettings()
  {
    DialogSettings root = new DialogSettings(IJAXRSUIConstants.SETTINGS_ROOT);
    dialogSettings.addSection(root);
    root.put(SETTINGS_SERVLET, getJAXRSServletName());
    LibraryInstallDelegate librariesInstallDelegate = (LibraryInstallDelegate) getDataModel().getProperty(LIBRARY_PROVIDER_DELEGATE);
    root.put(new String (librariesInstallDelegate.getLibraryProvider().getId() + SETTINGS_SERVLET_CLASSNAME), getJAXRSServletClassname());
    DialogSettings mappings = new DialogSettings(SETTINGS_URL_MAPPINGS);
    root.addSection(mappings);
    mappings.put(SETTINGS_URL_PATTERN, getJAXRSPatterns());

  }

  private String getJAXRSServletName()
  {
    return servletInfoGroup.txtJAXRSServletName.getText().trim();
  }

  private String getJAXRSServletClassname()
  {
    return servletInfoGroup.txtJAXRSServletClassName.getText().trim();
  }

  private String[] getJAXRSPatterns()
  {
    return servletInfoGroup.lstJAXRSServletURLPatterns.getItems();
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * org.eclipse.wst.common.project.facet.ui.IFacetWizardPage#setConfig(java
   * .lang.Object)
   */
  public void setConfig(Object config)
  {
    model.removeListener(this);
    synchHelper.dispose();

    model = (IDataModel) config;
    model.addListener(this);
    synchHelper = initializeSynchHelper(model);
    model.setStringProperty(IJAXRSFacetInstallDataModelProperties.EARPROJECT_NAME, sEARProject);
    model.setStringProperty(IJAXRSFacetInstallDataModelProperties.WEBPROJECT_NAME, sWEBProject);
    model.setStringProperty(IJAXRSFacetInstallDataModelProperties.TARGETRUNTIME, sTargetRuntime);
    model.setBooleanProperty(IJAXRSFacetInstallDataModelProperties.ADD_TO_EAR, bAddToEAR);
    
    model.setProperty(IJAXRSFacetInstallDataModelProperties.SERVER_IRUNTIME, targetRuntime);
    model.setProperty(IJAXRSFacetInstallDataModelProperties.CONFIGURATION_PRESET, selectedPreset);
    model.setProperty(IJAXRSFacetInstallDataModelProperties.EARPROJECTS, earProjects);

  }

  /*
   * (non-Javadoc)
   * 
   * @seeorg.eclipse.wst.common.project.facet.ui.IFacetWizardPage#
   * transferStateToConfig()
   */
  public void transferStateToConfig()
  {
    saveSettings();
  }

  private void addModificationListeners()
  {
// jaxrsLibCfgComp.setSynchHelper(synchHelper);
    synchHelper.synchText(servletInfoGroup.txtJAXRSServletName, SERVLET_NAME, null);
    synchHelper.synchText(servletInfoGroup.txtJAXRSServletClassName, SERVLET_CLASSNAME, null);
    synchHelper.synchList(servletInfoGroup.lstJAXRSServletURLPatterns, SERVLET_URL_PATTERNS, null);
    synchHelper.synchCheckbox(updateDDCheckBox, UPDATEDD, null);
  }

  private void loadURLMappingPatterns(IDialogSettings root)
  {
    servletInfoGroup.lstJAXRSServletURLPatterns.removeAll();
    IDialogSettings mappings = null;
    if (root != null)
      mappings = root.getSection(SETTINGS_URL_MAPPINGS);
    String[] patterns = null;
    if (mappings != null)
      patterns = mappings.getArray(SETTINGS_URL_PATTERN);

    if (patterns == null || patterns.length == 0)
    {
      patterns = (String[]) model.getDefaultProperty(IJAXRSFacetInstallDataModelProperties.SERVLET_URL_PATTERNS);
    }
    for (int i = 0; i < patterns.length; i++)
    {
      addItemToList(patterns[i], false);
    }
  }

  private void addItemToList(String pattern, boolean selectMe)
  {
    servletInfoGroup.lstJAXRSServletURLPatterns.add(pattern == null ? "" : pattern); //$NON-NLS-1$
    if (pattern == null && selectMe)
      servletInfoGroup.lstJAXRSServletURLPatterns.setSelection(servletInfoGroup.lstJAXRSServletURLPatterns.getItemCount() - 1);
    // When 119321 is fixed - remove code below
    updateModelForURLPattern();
  }

  private void removeItemFromList(String[] selection)
  {
    for (int i = 0; i < selection.length; i++)
    {
      String sel = selection[i];
      servletInfoGroup.lstJAXRSServletURLPatterns.remove(sel);
    }
    // When 119321 is fixed - remove code below
    updateModelForURLPattern();
  }

  private void updateModelForURLPattern()
  {
    model.setProperty(IJAXRSFacetInstallDataModelProperties.SERVLET_URL_PATTERNS, servletInfoGroup.lstJAXRSServletURLPatterns.getItems());
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * org.eclipse.wst.common.frameworks.internal.datamodel.ui.DataModelWizardPage
   * #getValidationPropertyNames()
   */
  protected String[] getValidationPropertyNames()
  {
    return new String[] { SERVLET_NAME, SERVLET_CLASSNAME, LIBRARY_PROVIDER_DELEGATE, UPDATEDD };
  }

  /*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.wst.common.project.facet.ui.IFacetWizardPage#setWizardContext
	 * (org.eclipse.wst.common.project.facet.ui.IWizardContext)
	 */
	@SuppressWarnings("unchecked")
	public void setWizardContext(IWizardContext context) {
		// hook into web datamodel of new project wizard.
		this.context = context;
		sWEBProject = context.getProjectName();
		Iterator it = context.getSelectedProjectFacets().iterator();
		IProjectFacetVersion webFacetVersion = null;
		while (it.hasNext()) {
			// find Web facet
			IProjectFacetVersion pfv = (IProjectFacetVersion) it.next();
			if (pfv.getProjectFacet().getId().equals("jst.web")) { //$NON-NLS-1$
				webFacetVersion = pfv;
				break;
			}
		}
		if (webFacetVersion != null) {
			try {
				webAppDataModel = (IDataModel) context.getConfig(
						webFacetVersion, IFacetedProject.Action.Type.INSTALL,
						context.getProjectName());
				if (webAppDataModel == null) {
					// This means the web facet has already been installed!
					isProjectCreationMode = false;
					IProject webProject = ResourcesPlugin.getWorkspace()
							.getRoot().getProject(sWEBProject);

					org.eclipse.wst.common.project.facet.core.runtime.IRuntime rt = ProjectFacetsManager
							.create(webProject).getPrimaryRuntime();
					if (rt != null) {
						IRuntime runtime = FacetUtil.getRuntime(rt);
						if (runtime != null) {
							targetRuntime = runtime;
							IRuntimeType rtType = runtime.getRuntimeType();
							if (rtType != null) {
								sTargetRuntime = rtType.getId();
							}
	
							if (webProject != null) {
								IProject[] referencingEARProjects = EarUtilities
										.getReferencingEARProjects(webProject);
								int size = referencingEARProjects.length;
	
								if (size == 1) {
									String earName = referencingEARProjects[0]
											.getName();
									// Since we do have only one EAR, let's use
									// the existing 'support/variables' and
									// continue as usual
									// The two properties, ADD_TO_EAR and
									// EARPROJECT_NAME will be set.
									this.bAddToEAR = true;
									this.sEARProject = earName;
								} else if (size > 1) {
									// On the other hand, if we have multiple
									// ears, then we need to use the new
									// property EARPROJECTS
									// Perhaps we can just use this new property
									// to handle the case for only one EAR.
									this.bAddToEAR = true;
									this.earProjects = new ArrayList<IProject>();
									String earName = referencingEARProjects[0]
											.getName();
									this.sEARProject = earName;
									for (int i = 0; i < size; i++) {
										earProjects.add(referencingEARProjects[i]);
									}
								}
							}
						}
					}
				} else {
					Object oAddToEAR = webAppDataModel
							.getProperty(IJ2EEModuleFacetInstallDataModelProperties.ADD_TO_EAR);
					Object oTargetRuntime = webAppDataModel
							.getProperty(IJ2EEModuleFacetInstallDataModelProperties.FACET_RUNTIME);
					if (oAddToEAR != null) {
						if (((Boolean) oAddToEAR).booleanValue() == true) {
							bAddToEAR = true;
							Object oEARProjectName = webAppDataModel
									.getProperty(IJ2EEModuleFacetInstallDataModelProperties.EAR_PROJECT_NAME);
							if (oEARProjectName != null) {
								this.sEARProject = (String) oEARProjectName;

							}
						}
					}
					if (oTargetRuntime != null
							&& oTargetRuntime instanceof BridgedRuntime) {
						BridgedRuntime br = (BridgedRuntime) oTargetRuntime;
						if (br != null) {
							IRuntime runtime = FacetUtil.getRuntime(br);
							if (runtime != null) {
								IRuntimeType rtType = runtime.getRuntimeType();
								if (rtType != null)
									sTargetRuntime = rtType.getId();
							}
						}
					}

				}

				if (webAppDataModel != null) {
					webAppDataModel.addListener(this);
				}
			} catch (CoreException e) {
				JAXRSUIPlugin.log(IStatus.ERROR,
						Messages.JAXRSFacetInstallPage_ErrorNoWebAppDataModel,
						e);
			}
		} 
	}

  /*
   * (non-Javadoc)
   * 
   * @see
   * org.eclipse.wst.common.frameworks.internal.datamodel.ui.DataModelWizardPage
   * #
   * propertyChanged(org.eclipse.wst.common.frameworks.datamodel.DataModelEvent
   * )
   */
  public void propertyChanged(DataModelEvent event)
  {

    if (webAppDataModel != null)
    {
      String propertyName = event.getPropertyName();
      if (propertyName.equals(IJ2EEModuleFacetInstallDataModelProperties.CONFIG_FOLDER))
      {
        model.setStringProperty(WEBCONTENT_DIR, event.getProperty().toString());
      }
      else if (propertyName.equals(IJ2EEModuleFacetInstallDataModelProperties.ADD_TO_EAR))
      {
        model.setBooleanProperty(ADD_TO_EAR, ((Boolean) event.getProperty()).booleanValue());
      }
      else if (propertyName.equals(IJ2EEModuleFacetInstallDataModelProperties.FACET_PROJECT_NAME))
      {
        model.setStringProperty(WEBPROJECT_NAME, event.getProperty().toString());
      }
      else if (propertyName.equals(IJ2EEModuleFacetInstallDataModelProperties.EAR_PROJECT_NAME))
      {
        model.setStringProperty(EARPROJECT_NAME, event.getProperty().toString());
      }
      else if (propertyName.equals(IJAXRSFacetInstallDataModelProperties.LIBRARY_PROVIDER_DELEGATE))
      {
      	LibraryInstallDelegate librariesInstallDelegate = (LibraryInstallDelegate) getDataModel().getProperty(LIBRARY_PROVIDER_DELEGATE);
		LibraryProviderOperationConfig config = librariesInstallDelegate.getLibraryProviderOperationConfig();

        if (event.getProperty() != null) {

       		String libraryProviderID = librariesInstallDelegate.getLibraryProvider().getId();
       		ILibraryProvider thisProvider = librariesInstallDelegate.getLibraryProvider();
			try {
				//we are sometimes notified when the user has not actually changed the selected library type
				if (currentlySelectedLibraryType != thisProvider) {
					//only update servlet class name & update DD state when library 
					//type has changed
					currentlySelectedLibraryType = thisProvider;
					updateUpdateDDState(libraryProviderID);
					updateServletClassName(libraryProviderID);
				}
			} catch (Exception e) {
				//TODO exception as we are notified in non-UI thread and Invalid thread access exception,
				//should find another way to get notified when library provider changes
			}
        }
		if (config instanceof JAXRSUserLibraryProviderInstallOperationConfig) {
		  JAXRSUserLibraryProviderInstallOperationConfig customConfig = (JAXRSUserLibraryProviderInstallOperationConfig) config;
		  customConfig.setModel(getDataModel());
		} else if (config instanceof JAXRSSharedLibraryProviderInstallOperationConfig) {
		  JAXRSSharedLibraryProviderInstallOperationConfig customConfig = (JAXRSSharedLibraryProviderInstallOperationConfig) config;
		  customConfig.setModel(getDataModel());
		}
      }
    }
    super.propertyChanged(event);
  }

  private void updateServletClassName(String libraryProviderID) {
	  servletInfoGroup.txtJAXRSServletClassName.setText(JAXRSLibraryProviderUtil.getServletClassName(libraryProviderID));
  }

/*
   * (non-Javadoc)
   * 
   * @see
   * org.eclipse.wst.common.frameworks.internal.datamodel.ui.DataModelWizardPage
   * #dispose()
   */
  public void dispose()
  {
    if (webAppDataModel != null)
      webAppDataModel.removeListener(this);

    if (model != null)
      model.removeListener(this);
// jaxrsLibCfgComp.dispose();
    super.dispose();
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * org.eclipse.wst.common.frameworks.internal.datamodel.ui.DataModelWizardPage
   * #restoreDefaultSettings()
   */
  protected void restoreDefaultSettings()
  {
    initializeValues();

// checkToCompletePage(jaxrsLibCfgComp);
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * org.eclipse.wst.common.frameworks.internal.datamodel.ui.DataModelWizardPage
   * #showValidationErrorsOnEnter()
   */
  protected boolean showValidationErrorsOnEnter()
  {
    return true;
  }
  @Override
  public boolean isPageComplete()
  {
      final LibraryInstallDelegate librariesInstallDelegate = (LibraryInstallDelegate) getDataModel().getProperty(LIBRARY_PROVIDER_DELEGATE);
      if (librariesInstallDelegate == null)
          throw new IllegalArgumentException("LibraryInstallDelegate is expected to be non-null"); //$NON-NLS-1$

      return super.isPageComplete() && (librariesInstallDelegate.validate().getSeverity() != IStatus.ERROR);
  }


	private void setChildrenEnabled(Composite parentComposite, boolean enabled) {
		Control[] wsdlControls = parentComposite.getChildren();
		for (int i = 0; i < wsdlControls.length; i++) {
			wsdlControls[i].setEnabled(enabled);
		}
	}

}
