package com.netifera.platform.net.http.internal.web.model; import java.net.URI; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import com.netifera.platform.api.model.IModelPredicate; import com.netifera.platform.api.model.IModelService; import com.netifera.platform.api.model.IWorkspace; import com.netifera.platform.net.http.web.model.HTTPBasicAuthenticationEntity; import com.netifera.platform.net.http.web.model.HTTPRequestEntity; import com.netifera.platform.net.http.web.model.HTTPResponseEntity; import com.netifera.platform.net.http.web.model.IWebEntityFactory; import com.netifera.platform.net.http.web.model.WebApplicationEntity; import com.netifera.platform.net.http.web.model.WebFormAuthenticationEntity; import com.netifera.platform.net.http.web.model.WebPageEntity; import com.netifera.platform.net.http.web.model.WebSiteEntity; import com.netifera.platform.net.model.ClientEntity; import com.netifera.platform.net.model.ClientServiceConnectionEntity; import com.netifera.platform.net.model.INetworkEntityFactory; import com.netifera.platform.net.model.ServiceEntity; import com.netifera.platform.util.addresses.inet.InternetAddress; import com.netifera.platform.util.locators.TCPSocketLocator; public class WebEntityFactory implements IWebEntityFactory { private IModelService model; private INetworkEntityFactory networkEntityFactory; // private IDomainEntityFactoryService domainEntityFactory; private IWorkspace getWorkspace() { if(model.getCurrentWorkspace() == null) { throw new IllegalStateException("Cannot create web entities because no workspace is currently open"); } return model.getCurrentWorkspace(); } protected void setModelService(IModelService model) { this.model = model; } protected void unsetModelService(IModelService model) { this.model = null; } protected void setNetworkEntityFactory(INetworkEntityFactory factory) { networkEntityFactory = factory; } protected void unsetNetworkEntityFactory(INetworkEntityFactory factory) { networkEntityFactory = null; } public synchronized ServiceEntity createWebServer(final long realm, long space, TCPSocketLocator http, String product) { Map<String,String> info = new HashMap<String,String>(); info.put("serviceType", "HTTP"); if (product != null) info.put("product", product); return networkEntityFactory.createService(realm, space, http, "HTTP", info); } // TODO add Domain from hostname public synchronized WebSiteEntity createWebSite(final long realm, long spaceId, TCPSocketLocator http, String hostname) { assert http != null; if (hostname == null || hostname.equals(http.getAddress().toString())) { hostname = ""; } hostname = hostname.toLowerCase(Locale.ENGLISH); WebSiteEntity answer = (WebSiteEntity) getWorkspace().findByKey(WebSiteEntity.createQueryKey(realm, http.getAddress(), http.getPort(), hostname)); if(answer == null) { ServiceEntity service = createWebServer(realm, spaceId, http, null); answer = new WebSiteEntity(getWorkspace(), realm, service, hostname); answer.save(); } else { answer.getHTTP().addToSpace(spaceId); } answer.addToSpace(spaceId); return answer; } //XXX space not used? should notify? public synchronized void setFavicon(long realm, long space, TCPSocketLocator http, URI url, byte[] faviconBytes) { WebSiteEntity webSite = createWebSite(realm, space, http, url.getHost()); webSite.setFavicon(faviconBytes); webSite.update(); } public synchronized WebPageEntity createWebPage(final long realm, long spaceId, TCPSocketLocator http, URI url, String contentType) { final WebSiteEntity site = createWebSite(realm, spaceId, http, url.getHost()); final String path = url.normalize().getPath(); WebPageEntity answer = (WebPageEntity) getWorkspace().findByKey(WebPageEntity.createQueryKey(realm, http.getAddress(), http.getPort(), site.getHostName(), path)); if (answer != null) { answer.addToSpace(spaceId); return answer; } answer = new WebPageEntity(getWorkspace(), realm, site, path, contentType); answer.save(); answer.addToSpace(spaceId); return answer; } public synchronized WebApplicationEntity createWebApplication(final long realm, long spaceId, TCPSocketLocator http, URI url, Map<String, String> info) { final ServiceEntity service = createWebServer(realm, spaceId, http, null); final String urlString = url.toString(); List<WebApplicationEntity> results = getWorkspace().findByPredicate(WebApplicationEntity.class, new IModelPredicate<WebApplicationEntity>() { public boolean match(WebApplicationEntity candidate) { return candidate.getRealmId() == realm && candidate.getHTTP() == service && (candidate.getURL().startsWith(urlString) || urlString.startsWith(candidate.getURL())); } }); if(results.size() > 0) { WebApplicationEntity answer = results.get(0); if (!answer.getURL().equals(urlString) && answer.getURL().startsWith(urlString)) { answer.setURL(urlString); answer.update(); } answer.addToSpace(spaceId); return answer; } WebApplicationEntity answer = new WebApplicationEntity(getWorkspace(), realm, service.createReference(), urlString, info.get("serviceType")); if (info.get("version") != null) answer.setVersion(info.get("version")); answer.save(); answer.addToSpace(spaceId); return answer; } public synchronized HTTPBasicAuthenticationEntity createBasicAuthentication(final long realm, long spaceId, TCPSocketLocator http, URI url, final String authenticationRealm) { final ServiceEntity service = createWebServer(realm, spaceId, http, null); HTTPBasicAuthenticationEntity answer = (HTTPBasicAuthenticationEntity) getWorkspace().findByKey(HTTPBasicAuthenticationEntity.createQueryKey(realm, http.getAddress(), http.getPort(), authenticationRealm)); if (answer != null) { answer.addToSpace(spaceId); } else { answer = new HTTPBasicAuthenticationEntity(getWorkspace(), realm, service.createReference(), authenticationRealm); answer.save(); answer.addToSpace(spaceId); } WebPageEntity page = createWebPage(realm, spaceId, http, url, null); page.setAuthentication(answer); page.update(); return answer; } @Deprecated // TODO public synchronized WebFormAuthenticationEntity createFormAuthentication(long realm, long space, TCPSocketLocator http, URI url, String usernameField, String passwordField) { // TODO Auto-generated method stub return null; } // TODO split createRequest+createResponse for (sniffed) asymetric traffic public synchronized HTTPRequestEntity createRequestResponse(final long realm, long spaceId, InternetAddress clientAddress, Map<String,String> clientInfo, TCPSocketLocator http, String requestLine, String responseStatusLine, String contentType) { ServiceEntity service = createWebServer(realm, spaceId, http, null); ClientEntity client = networkEntityFactory.createClient(realm, spaceId, clientAddress, "HTTP", clientInfo, null); ClientServiceConnectionEntity connection = networkEntityFactory.createConnection(spaceId, client, service, null); HTTPRequestEntity answer = new HTTPRequestEntity(getWorkspace(), connection, requestLine); HTTPResponseEntity response = new HTTPResponseEntity(getWorkspace(), connection, responseStatusLine); if (contentType != null) response.setNamedAttribute("Content-Type", contentType); response.save(); response.addToSpace(spaceId); answer.setResponse(response); answer.save(); answer.addToSpace(spaceId); return answer; } }