[434185] Server Discovery should allow sites without site.xml
diff --git a/plugins/org.eclipse.wst.server.discovery/META-INF/MANIFEST.MF b/plugins/org.eclipse.wst.server.discovery/META-INF/MANIFEST.MF
index 9e20e8d..180f2ce 100644
--- a/plugins/org.eclipse.wst.server.discovery/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.wst.server.discovery/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %bundleName
 Bundle-Vendor: %bundleVendor
 Bundle-SymbolicName: org.eclipse.wst.server.discovery;singleton:=true
-Bundle-Version: 1.0.600.qualifier
+Bundle-Version: 1.0.700.qualifier
 Bundle-Activator: org.eclipse.wst.server.discovery.internal.Activator
 Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0)",
  org.eclipse.ui;bundle-version="[3.5.0,4.0)",
diff --git a/plugins/org.eclipse.wst.server.discovery/pom.xml b/plugins/org.eclipse.wst.server.discovery/pom.xml
index 1330ae0..87a0dbc 100644
--- a/plugins/org.eclipse.wst.server.discovery/pom.xml
+++ b/plugins/org.eclipse.wst.server.discovery/pom.xml
@@ -22,6 +22,6 @@
 

   <groupId>org.eclipse.webtools.servertools</groupId>

   <artifactId>org.eclipse.wst.server.discovery</artifactId>

-  <version>1.0.600-SNAPSHOT</version>

+  <version>1.0.700-SNAPSHOT</version>

   <packaging>eclipse-plugin</packaging>

 </project>

diff --git a/plugins/org.eclipse.wst.server.discovery/src/org/eclipse/wst/server/discovery/internal/model/ExtensionUpdateSite.java b/plugins/org.eclipse.wst.server.discovery/src/org/eclipse/wst/server/discovery/internal/model/ExtensionUpdateSite.java
index d340c14..27312f3 100644
--- a/plugins/org.eclipse.wst.server.discovery/src/org/eclipse/wst/server/discovery/internal/model/ExtensionUpdateSite.java
+++ b/plugins/org.eclipse.wst.server.discovery/src/org/eclipse/wst/server/discovery/internal/model/ExtensionUpdateSite.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2008, 2010 IBM Corporation and others.
+ * Copyright (c) 2008, 2015 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
@@ -16,14 +16,15 @@
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.equinox.internal.p2.updatesite.metadata.UpdateSiteMetadataRepositoryFactory;
-import org.eclipse.equinox.p2.engine.IProfile;
-import org.eclipse.equinox.p2.engine.IProfileRegistry;
+import org.eclipse.equinox.p2.core.IProvisioningAgent;
+import org.eclipse.equinox.p2.core.ProvisionException;
 import org.eclipse.equinox.p2.metadata.IInstallableUnit;
 import org.eclipse.equinox.p2.metadata.IRequirement;
 import org.eclipse.equinox.p2.metadata.expression.IMatchExpression;
 import org.eclipse.equinox.p2.query.*;
 import org.eclipse.equinox.p2.repository.IRepositoryManager;
 import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
+import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager;
 import org.eclipse.wst.server.discovery.internal.ExtensionUtility;
 import org.eclipse.wst.server.discovery.internal.Trace;
 import org.osgi.framework.BundleContext;
@@ -34,6 +35,7 @@
 */
 public class ExtensionUpdateSite {
 	private static final List<String> EMPTY_LIST = new ArrayList<String>(0);
+	public static final String SERVER_ADAPTER_ID = "org.eclipse.wst.server.core.serverAdapter"; //$NON-NLS-1$
 
 	private String url;
 	private String featureId;
@@ -65,63 +67,104 @@
 
 	public List<Extension> getExtensions(IProgressMonitor monitor) throws CoreException {
 		try {
-			UpdateSiteMetadataRepositoryFactory mrf = new UpdateSiteMetadataRepositoryFactory();
-
+			/*
+			 * To discovery the server adapter, there are three methods:
+			 * 1. Looking at the site.xml (if it exists). This is the legacy method
+			 * 2. Looking for the org.eclipse.wst.server.core.serverAdapter property in a p2
+			 *    update site (that may not have a site.xml). The property is necessary to identify
+			 *    the InstallableUnit as a server type. Otherwise, all the InstallableUnits will show
+			 *    up regardless of whether it is a server or not
+			 * 3. If the user created the p2 update site using a category.xml file (migrating old site.xml
+			 *    to use category.xml)
+			 */	
 			BundleContext bd = org.eclipse.wst.server.discovery.internal.Activator.getDefault().getBundle().getBundleContext();			
-			mrf.setAgent(ExtensionUtility.getAgent(bd));
+			IProvisioningAgent agent = ExtensionUtility.getAgent(bd);
 			
 			URI url2 = new URI(url);
-			IMetadataRepository repo = mrf.load(url2, IRepositoryManager.REPOSITORIES_ALL, monitor);
-			//Query query = new InstallableUnitQuery("org.eclipse.wst.server.core.serverAdapter");
-			//Query query = CompoundQuery.createCompoundQuery(new Query[] {new
-			//		IUPropertyQuery(IInstallableUnit.PROP_TYPE_CATEGORY, Boolean.toString(true)),
-			//		new IUPropertyQuery(IInstallableUnit.PROP_NAME,"org.eclipse.wst.server.core.serverAdapter")}, true);
 			
-//---->>>>
-			IProfileRegistry profileRegistry = (IProfileRegistry) ExtensionUtility.getService(bd, IProfileRegistry.class.getName());
-			IProfile[] profiles = profileRegistry.getProfiles();
-			IProfile profile = profileRegistry.getProfile(IProfileRegistry.SELF);
-			
-			//IQuery<IInstallableUnit> query = QueryUtil.createIUAnyQuery();
-			//			IQuery<IInstallableUnit> query = QueryUtil.createIUQuery("org.eclipse.wst.server.core.serverAdapter");
-			//Query query = new InstallableUnitQuery("org.eclipse.wst.server.core.serverAdapter");
-			//List<String> list2 = new ArrayList();
-			//Query query = new ExtensionInstallableUnitQuery(list2);
-			//IQueryResult<IInstallableUnit> collector = profile.query(query, monitor);
-//<-------	
-			
-			//IQuery<IInstallableUnit> query = QueryUtil.createIUCategoryQuery();
-			IQuery<IInstallableUnit> query = QueryUtil.createMatchQuery("id ~=/*org.eclipse.wst.server.core.serverAdapter/");
-
-			IQueryResult<IInstallableUnit> collector = repo.query(query, monitor);
-			
+			// Method 1: Looking at the site.xml
+			UpdateSiteMetadataRepositoryFactory mrf = new UpdateSiteMetadataRepositoryFactory();
+			mrf.setAgent(ExtensionUtility.getAgent(bd));
+			// If the site.xml does not exist, the load will throw a org.eclipse.equinox.p2.core.ProvisionException
 			List<Extension> list = new ArrayList<Extension>();
-			for (IInstallableUnit iu: collector.toUnmodifiableSet()) {
-				Collection<IRequirement> req = iu.getRequirements();
-				if (req != null) {
-					for (IRequirement requirement : req) {
-						
-						//IMatchExpression<IInstallableUnit> matches = requirement.getMatches();
-						//query = QueryUtil.createQuery(matches);
-						IMatchExpression<IInstallableUnit> matches = requirement.getMatches();
-						query = new ExpressionMatchQuery<IInstallableUnit>(IInstallableUnit.class, matches);
+			try {
+				IMetadataRepository repo = mrf.load(url2, IRepositoryManager.REPOSITORIES_ALL, monitor);
+				IQuery<IInstallableUnit> query = QueryUtil.createMatchQuery("id ~=/*org.eclipse.wst.server.core.serverAdapter/"); //$NON-NLS-1$
+				
+				list = getInstallableUnits(repo,query,url2,monitor);			
+			}
+			catch (ProvisionException pe){
+				Trace.trace(Trace.WARNING, "Error getting update site information", pe); //$NON-NLS-1$
+			}
 
-					    IQueryResult<IInstallableUnit> collector2 = repo.query(query, monitor);						
-						Iterator<IInstallableUnit> iter2 = collector2.iterator();
-						while (iter2.hasNext()) {
-							IInstallableUnit iu2 = iter2.next();
-							if (!list.contains(iu2)) {
-								Extension ext = new Extension(iu2, url2);
-								list.add(ext);
+			// Call Method 2 if there are no results from Method 1 (e.g. if the site.xml exists without
+			// specifying any server adapters there or no site.xml exists)
+			if (list.isEmpty()){
+				IMetadataRepositoryManager manager = (IMetadataRepositoryManager) agent.getService(IMetadataRepositoryManager.SERVICE_NAME);
+				manager.addRepository(url2);
+				// Need to query for all IUs
+				IQuery<IInstallableUnit> query = QueryUtil.createIUAnyQuery();
+				
+				IMetadataRepository repo = manager.loadRepository(url2, monitor);				
+				List<Extension> list2 = getInstallableUnits(repo,query,url2,monitor);
+				
+				int size = list2.size();
+				for (int i=0;i<size;i++){
+					Extension e = list2.get(i);
+					IInstallableUnit[] iuArr = e.getIUs();
+					if(iuArr != null && iuArr.length > 0){
+						if (iuArr[0] != null){
+							if (iuArr[0].getProperty(SERVER_ADAPTER_ID) != null){
+								list.add(e);
 							}
 						}
+						
+					}
+				}
+			}
+			
+			// Call Method 3 if no results from Method 2. Creating the p2 update site using the category.xml will generate
+			// a provider property with org.eclipse.wst.server.core.serverAdapter
+			if (list.isEmpty()){
+				IMetadataRepositoryManager manager = (IMetadataRepositoryManager) agent.getService(IMetadataRepositoryManager.SERVICE_NAME);
+				manager.addRepository(url2);
+				IQuery<IInstallableUnit> query = QueryUtil.createMatchQuery("id ~=/*org.eclipse.wst.server.core.serverAdapter/"); //$NON-NLS-1$
+				
+				IMetadataRepository repo = manager.loadRepository(url2, monitor);				
+				list = getInstallableUnits(repo,query,url2,monitor);
+			}			
+			
+			return list;
+		} catch (Exception e) {
+			Trace.trace(Trace.WARNING, "Error getting update info", e); //$NON-NLS-1$
+			return new ArrayList<Extension>(0);
+		}
+	}
+	
+	// Get the list of InstallableUnits and all its requirements
+	protected List<Extension> getInstallableUnits(IMetadataRepository repo, IQuery<IInstallableUnit> query, URI url, IProgressMonitor monitor){
+		List<Extension> list = new ArrayList<Extension>();
+		IQueryResult<IInstallableUnit> collector = repo.query(query, monitor);
+
+		for (IInstallableUnit iu: collector.toUnmodifiableSet()) {
+			Collection<IRequirement> req = iu.getRequirements();
+			if (req != null) {
+				for (IRequirement requirement : req) {
+					IMatchExpression<IInstallableUnit> matches = requirement.getMatches();
+					query = new ExpressionMatchQuery<IInstallableUnit>(IInstallableUnit.class, matches);
+
+				    IQueryResult<IInstallableUnit> collector2 = repo.query(query, monitor);						
+					Iterator<IInstallableUnit> iter2 = collector2.iterator();
+					while (iter2.hasNext()) {
+						IInstallableUnit iu2 = iter2.next();
+						if (!list.contains(iu2)) {
+							Extension ext = new Extension(iu2, url);
+							list.add(ext);
+						}
 					}
 				}
 			}
-			return list;
-		} catch (Exception e) {
-			Trace.trace(Trace.WARNING, "Error getting update info", e);
-			return new ArrayList<Extension>(0);
 		}
+		return list;
 	}
 }
\ No newline at end of file