package data
{
import events.ConfigChangeEvent;
import events.LoginEvent;
import flash.display.DisplayObject;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IOErrorEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLRequestHeader;
import flash.net.URLRequestMethod;
import mx.binding.utils.BindingUtils;
import mx.collections.XMLListCollection;
import mx.controls.Alert;
import mx.core.Application;
import mx.events.CollectionEvent;
import mx.events.PropertyChangeEvent;
import mx.managers.PopUpManager;
import mx.resources.IResourceManager;
import mx.resources.ResourceManager;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.http.HTTPService;
import panels.ServerLoginPanel;
[Event(name="ready")]
[Event(name="serverCacheDropped")]
public class DataSource extends EventDispatcher
{
[Bindable]
public var contextTree:XMLListCollection = new XMLListCollection();
[Bindable]
public var serverTree:XMLListCollection = new XMLListCollection();
[Bindable]
public var guiTree:XMLListCollection = new XMLListCollection();
[Bindable]
public var defaultConfig:XML;
[Bindable]
public var properties:XML;
[Bindable]
public var resourceManager:IResourceManager = ResourceManager.getInstance();
private var serverProps:XMLListCollection = new XMLListCollection();
private var layerProps:XMLListCollection = new XMLListCollection();
private var contextProps:XMLListCollection = new XMLListCollection();
private var mapProps:XMLListCollection = new XMLListCollection();
private var queryAspectProps:XMLListCollection = new XMLListCollection();
private var templateProps:XMLListCollection = new XMLListCollection();
private var reportProps:XMLListCollection = new XMLListCollection();
private var guiConfigProps:XMLListCollection = new XMLListCollection();
private var fullPropsLoading:Object = new Object();
private var lastId:Number = 0;
private var _serverUrl:String;
private var _proxyServerUrl:String;
private var _login:String;
private var _defaultConfigUrl:String;
private var _propertiesUrl:String;
namespace wfs = "http://www.opengis.net/wfs";
namespace xsd = "http://www.w3.org/2001/XMLSchema";
use namespace wfs;
use namespace xsd;
private var entityNames:Array = ["Context", "Layer", "Map", "QueryAspect",
"Report", "Server", "Template"];
private function reloadProxy():void
{
var proxyReload:URLLoader = new URLLoader();
proxyReload.addEventListener(Event.COMPLETE, function():void {
var resp:Object = XML(proxyReload.data).localName();
});
proxyReload.load(new URLRequest(this._proxyServerUrl + "/?service=reload"));
}
public function logout(callback:Function):void {
var logoutLoader:URLLoader = new URLLoader();
logoutLoader.addEventListener(Event.COMPLETE, function():void
{
callback();
});
logoutLoader.load(new URLRequest(_serverUrl + "request=Logout"));
}
private function createContextTree():XML {
var contexts:XML = ;
for(var i:int = 0; i < contextProps.length; i++) {
var context:XML = XML(contextProps.getItemAt(i));
var contextRef:XML = newRef(context);
contexts.appendChild(contextRef);
}
return contexts;
}
private function updateStatusAttributes(list:XMLList):void {
for each(var item:XML in list) {
var props:XML = getProps(item);
if(props.@status != item.@status) {
item.@status = props.@status;
}
}
}
private function updateContextTree():void {
updateStatusAttributes(contextTree.source..Context);
updateStatusAttributes(contextTree.source..Context);
updateStatusAttributes(contextTree.source..Layer);
updateStatusAttributes(contextTree.source..Map);
updateStatusAttributes(contextTree.source..QueryAspect);
updateStatusAttributes(contextTree.source..Report);
updateStatusAttributes(contextTree.source..Template);
}
private function buildServerTree():void {
var servers:XML = ;
for each(var server:XML in serverProps) {
servers.appendChild(newRef(server));
}
serverTree.removeAll();
serverTree.addItem(servers);
}
private function buildContextTree():void {
contextTree.removeAll();
contextTree.addItem(createContextTree());
}
private function buildGUIDataSource():void{
var newConfigList:XMLList = new XMLList();
for each(var config:XML in guiConfigProps) {
newConfigList += refactorGuiConfig(config);
}
guiConfigProps.source = newConfigList;
buildConfigTree();
}
public function buildConfigTree():void{
var tree:XML = ;
for each(var config:XML in guiConfigProps) {
tree.appendChild(deleteConfigTagsToHide(config.copy()));
}
var treeList:XMLList = XMLList(tree);
guiTree.source = treeList;
guiTree.source = treeList;
}
private function refactorGuiConfig(guiConfig:XML):XML{
var newConfig:XML = new XML(defaultConfig);
newConfig.@name = guiConfig.@name;
newConfig.Description = guiConfig.Description;
var colorNodes:XMLList = newConfig.Colors.children();
for(var i:Number=0;i 0){
colorNodes[i] = guiConfig.Colors.child(colorName)[0];
}
}
newConfig.ButtonBars = guiConfig.ButtonBars;
var buttonsOnBars:XMLList = newConfig.ButtonBars.ButtonBar.Buttons.children();
var buttonNodes:XMLList = newConfig.ActionButtons.children();
buttonNodes += newConfig.PaneButtons.children();
buttonNodes += newConfig.MapViewerButtons.children();
for each(var buttonNode:XML in buttonNodes){
buttonNode.@used="false";
for each (var buttonOnBar:XML in buttonsOnBars){
if(buttonOnBar.@name==buttonNode.Name){
buttonOnBar.@datatip = buttonNode.ToolTipText.child(String(resourceManager.localeChain[0]).substr(0, 2))[0];
}
}
}
var orgButtonNodes:XMLList = guiConfig.ActionButtons.children();
orgButtonNodes += guiConfig.PaneButtons.children();
orgButtonNodes += guiConfig.MapViewerButtons.children();
for(var j:Number=0;j 0) {
return props.Owner == _login;
}
return false;
}
private function isClientId(item:XML):Boolean {
return item.child("@clientId").length() > 0 && item.@clientId;
}
public function duplicateItem(item:XML, parentNode:XML):void {
item = getProps(item).copy();
while(!isUnique(item.localName(), item.Name, true)) {
item.Name += "_copy";
}
item.@clientId = true;
item.@status = "new";
item.@id = lastId++;
item.Owner = _login;
addItem(item, parentNode);
}
public function newRef(item:XML, subRef:Boolean = true):XML
{
var language:String = resourceManager.localeChain[0].toString().substr(0, 2);
item = getProps(item);
var localName:String = item.localName();
var itemRef:XML = <{localName}/>;
itemRef.@status = item.@status;
itemRef.@id = item.@id;
itemRef.@clientId = item.@clientId;
if(subRef) {
switch(localName) {
case "Map":
var layersNode:XML = ;
for each(var currentLayer:XML in item.Layers.Layer) {
var layerRef:XML = newRef(currentLayer);
layerRef.@status = currentLayer.@status;
layersNode.appendChild(layerRef);
}
itemRef.appendChild(layersNode);
var queryAspectsNode:XML = ;
var queryAspectsCollection:XMLListCollection
= new XMLListCollection(item.QueryAspects.QueryAspect);
/*var queryAspectsSort:Sort = new Sort();
var queryAspectsField:SortField = new SortField();
var defaultCompareFunction:Function = queryAspectsField.compareFunction;
queryAspectsField.compareFunction = function(a:Object, b:Object):int {
return defaultCompareFunction(getProps(XML(a)).Titles.Title.(Language == language).Title,
getProps(XML(b)).Titles.Title.(Language == language).Title);
}
queryAspectsSort.fields = [queryAspectsField];
queryAspectsCollection.sort = queryAspectsSort;
queryAspectsCollection.refresh();*/
for each(var currentQueryAspect:XML in queryAspectsCollection) {
var queryAspectRef:XML = newRef(currentQueryAspect);
// Use the same status as the reference in the entity (for deleted references)
queryAspectRef.@status = currentQueryAspect.@status;
queryAspectsNode.appendChild(queryAspectRef);
}
itemRef.appendChild(queryAspectsNode);
var templatesNode:XML = ;
for each(var currentTemplate:XML in item.Templates.Template) {
var templateRef:XML = newRef(currentTemplate);
templateRef.@status = currentTemplate.@status;
templatesNode.appendChild(templateRef);
}
itemRef.appendChild(templatesNode);
var reports:XML = ;
for each(var report:XML in reportProps) {
if(report.Map_id == item.@id
&& report.Map_id.@clientId == item.@clientId) {
var reportRef:XML = newRef(report);
reportRef.@status = report.@status;
reports.appendChild(reportRef);
}
}
itemRef.appendChild(reports);
break;
case "Context":
var maps:XML = ;
var mapsCollection:XMLlistCollection = new XMLListCollection(item.Maps.Map);
/*var mapsSort:Sort = new Sort();
var mapsField:SortField = new SortField();
defaultCompareFunction = mapsField.compareFunction;
mapsField.compareFunction = function(a:Object, b:Object):int {
return defaultCompareFunction(getProps(XML(a)).Titles.Title.(Language == language).Title,
getProps(XML(b)).Titles.Title.(Language == language).Title);
}
mapsSort.fields = [mapsField];
mapsCollection.sort = mapsSort;
mapsCollection.refresh();*/
for each(var map:XML in mapsCollection) {
var mapRef:XML = newRef(map);
mapRef.@status = map.@status;
maps.appendChild(mapRef);
}
itemRef.appendChild(maps);
break;
case "Layer":
var layerProps:XML = getProps(item);
if(layerProps.Type == "Group") {
for each(var subLayer:XML in layerProps.Layers.Layer) {
var subLayerRef:XML = newRef(subLayer);
// Use the same status as the reference in the entity (for deleted references)
subLayerRef.@status = subLayer.@status;
itemRef.appendChild(subLayerRef);
}
}
break;
}
}
return itemRef;
}
public function newLayer():XML
{
var newItem:XML =
Layer
en
nl
de
;
newItem.@id = lastId++;
newItem.Owner = _login;
//newItem.Server.@id = serverProps.source.Server[0].@id;
return newItem;
}
public function newGroupLayer():XML
{
var newItem:XML =
Group
en
nl
de
;
newItem.@id = lastId++;
newItem.Owner = _login;
return newItem;
}
public function newMap():XML
{
var newItem:XML =
;
newItem.@id = lastId++;
newItem.Owner = _login;
return newItem;
}
public function newServer():XML
{
var newItem:XML =
;
newItem.@id = lastId++;
newItem.Owner = _login;
return newItem;
}
public function newQueryAspect():XML
{
var newItem:XML =
en
nl
de
;
newItem.@id = lastId++;
newItem.Owner = _login;
return newItem;
}
public function newTemplate():XML
{
var newItem:XML =
en
nl
de
10
10
10
10
map
0
0
0
0
;
newItem.@id = lastId++;
newItem.Owner = _login;
return newItem;
}
public function newReport(map:XML):XML
{
var newItem:XML =
en
nl
de
{map.@id}
newItem.@id = lastId++;
return newItem;
}
public function newContext():XML
{
var newItem:XML =
newItem.@id = lastId++;
newItem.Owner = _login;
return newItem;
}
public function newButtonBar(buttonBars:XML):XML
{
var newItem:XML =
New ButtonBar
True
27
return newItem;
}
public function newConfig(configs:XML):XML
{
var newItem:XML = new XML(this.defaultConfig);
newItem.@name = '';
newItem.@id = lastId++;
newItem.@status = 'new';
newItem.@clientId = 'true';
newItem.Description = '';
return newItem;
}
private function getParentEntity(parentNode:XML):XML {
if(parentNode == null) {
return null;
}
while(entityNames.indexOf(parentNode.localName()) == -1) {
parentNode = parentNode.parent();
if(parentNode == null) {
return null;
}
}
return getProps(parentNode);
}
public function addRef(item:XML, parentNode:XML):void {
if(item.localName() == "Context" || item.localName() == "Server") {
parentNode = null;
getProps(item).@status = "deleted";
} else {
parentNode = getParentEntity(parentNode);
}
if(parentNode != null) {
XML(parentNode.child(item.localName() + "s")[0]).appendChild(newRef(item, false));
}
}
public function removeRef(item:XML, parentNode:XML):void {
if(item.localName() == "Context" || item.localName() == "Server") {
parentNode = null;
getProps(item).@status = "deleted";
} else {
parentNode = getParentEntity(parentNode);
}
if(parentNode != null) {
var items:XMLList = parentNode.descendants(item.localName());
for each(var currentItem:XML in items) {
if(currentItem.@id == item.@id
&& currentItem.@clientId == item.@clientId) {
currentItem.@status = "deleted";
}
}
}
}
public function addItem(newItem:XML, parentNode:XML):void
{
switch(newItem.localName()) {
case 'Geoide_Client_Config':
parentNode.appendChild(deleteConfigTagsToHide(newItem.copy()));
guiConfigProps.addItem(newItem);
return;
case 'ButtonBar':
getProps(parentNode.parent()).ButtonBars.appendChild(newItem);
parentNode.appendChild(newItem);
return;
}
if(newItem.localName() == "Context") {
parentNode = null;
} else {
parentNode = getParentEntity(parentNode);
}
switch(newItem.localName())
{
case 'Layer':
layerProps.addItem(newItem);
parentNode.Layers.Layer += newRef(newItem, false);
break;
case 'Map':
mapProps.addItem(newItem);
parentNode.Maps.Map += newRef(newItem, false);
break;
case 'Server':
serverProps.addItem(newItem);
break;
case 'Context':
contextProps.addItem(newItem);
break;
case 'QueryAspect':
queryAspectProps.addItem(newItem);
parentNode.QueryAspects.QueryAspect += newRef(newItem, false);
break;
case 'Template':
templateProps.addItem(newItem);
parentNode.Templates.Template += newRef(newItem, false);
break;
case 'Report':
reportProps.addItem(newItem);
parentNode.Reports.Report += newRef(newItem, false);
}
}
private function replaceClientId(clientId:Number, serverId:Number,
items:XMLList, recursive:Boolean = true):void
{
var newItems:XMLList = items.(@status == "new").(@id == clientId);
for each(var item:XML in newItems)
{
delete item.@clientId;
item.@id = serverId;
item.@status = "existing";
}
if(recursive)
{
for each(item in items)
{
replaceClientId(clientId, serverId, item.children());
}
}
}
private function setLayerId(list:XMLList, clientId:String, serverId:String):void {
for each(var layerRef:XML in list..Layer.
(attribute("clientId").length() > 0
&& @clientId.toString().toLowerCase() == "true"
&& @id == clientId)) {
layerRef.@id = serverId;
delete layerRef.@clientId;
layerRef.@status = "existing";
}
}
private function setMapId(list:XMLList, clientId:String, serverId:String):void {
for each(var mapRef:XML in list..Map.
(attribute("clientId").length() > 0
&& @clientId.toString().toLowerCase() == "true"
&& @id == clientId)) {
mapRef.@id = serverId;
delete mapRef.@clientId;
mapRef.@status = "existing";
}
}
private function setContextId(list:XMLList, clientId:String, serverId:String):void {
for each(var contextRef:XML in list..Context.
(attribute("clientId").length() > 0
&& @clientId.toString().toLowerCase() == "true"
&& @id == clientId)) {
contextRef.@id = serverId;
delete contextRef.@clientId;
contextRef.@status = "existing";
}
}
private function setTemplateId(list:XMLList, clientId:String, templateId:String):void {
for each(var templateRef:XML in list..Template.
(attribute("clientId").length() > 0
&& @clientId.toString().toLowerCase() == "true"
&& @id == clientId)) {
templateRef.@id = templateId;
delete templateRef.@clientId;
templateRef.@status = "existing";
}
}
private function setReportId(list:XMLList, clientId:String, reportId:String):void {
for each(var reportRef:XML in list..Report.
(attribute("clientId").length() > 0
&& @clientId.toString().toLowerCase() == "true"
&& @id == clientId)) {
reportRef.@id = reportId;
delete reportRef.@clientId;
reportRef.@status = "existing";
}
}
private function setQueryAspectId(list:XMLList, clientId:String, serverId:String):void {
for each(var queryAspectRef:XML in list..QueryAspect.
(attribute("clientId").length() > 0
&& @clientId.toString().toLowerCase() == "true"
&& @id == clientId)) {
queryAspectRef.@id = serverId;
delete queryAspectRef.@clientId;
queryAspectRef.@status = "existing";
}
}
private function setServerId(list:XMLList, clientId:String, serverId:String):void {
for each(var server:XML in list..Server.
(attribute("clientId").length() > 0
&& @clientId.toString().toLowerCase() == "true"
&& @id == clientId)) {
server.@id = serverId;
delete server.@clientId;
server.@status = 'existing';
}
for each(server in list..Featureserver.
(attribute("clientId").length() > 0
&& @clientId.toString().toLowerCase() == "true"
&& @id == clientId)) {
server.@id = serverId;
delete server.@clientId;
server.@status = 'existing';
}
}
private var transaction:XML;
public function save():void {
transaction =
{contextProps.source.copy().(@status == 'new')}
{layerProps.source.copy().(@status == 'new')}
{mapProps.source.copy().(@status == 'new')}
{queryAspectProps.source.copy().(@status == 'new')}
{templateProps.source.copy().(@status == 'new')}
{reportProps.source.copy().(@status == 'new')}
{serverProps.source.copy().(@status == 'new')}
{guiConfigProps.source.copy().(@status == 'new')}
{contextProps.source.copy().(@status == 'changed')}
{layerProps.source.copy().(@status == 'changed')}
{mapProps.source.copy().(@status == 'changed')}
{queryAspectProps.source.copy().(@status == 'changed')}
{templateProps.source.copy().(@status == 'changed')}
{reportProps.source.copy().(@status == 'changed')}
{serverProps.source.copy().(@status == 'changed')}
{guiConfigProps.source.copy().(@status == 'changed')}
{contextProps.source.copy().(@status == 'deleted' && @clientId == 'false')}
{layerProps.source.copy().(@status == 'deleted' && @clientId == 'false')}
{mapProps.source.copy().(@status == 'deleted' && @clientId == 'false')}
{queryAspectProps.source.copy().(@status == 'deleted' && @clientId == 'false')}
{templateProps.source.copy().(@status == 'deleted' && @clientId == 'false')}
{reportProps.source.copy().(@status == 'deleted' && @clientId == 'false')}
{serverProps.source.copy().(@status == 'deleted' && @clientId == 'false')}
{guiConfigProps.source.copy().(@status == 'deleted' && @clientId == 'false')}
;
var contextsUpdated:Boolean = transaction..Contexts.children().length() > 0;
var guiConfigsUpdated:Boolean = transaction..Geoide_Client_Configs.children().length() > 0;
var item:XML;
// remove deleted references
for each(item in transaction.Insert.descendants().(attribute("status").length() > 0 && @status == "deleted")) {
delete transaction.Insert.descendants().(copy() == item)[0];
}
for each(item in transaction.Update.descendants().(attribute("status").length() > 0 && @status == "deleted")) {
delete transaction.Update.descendants().(copy() == item)[0];
}
// remove status attributes
for each(item in transaction.descendants()) {
delete item.@status;
}
// Send transaction to server
var doTransactionRequest:URLLoader = new URLLoader();
doTransactionRequest.addEventListener(IOErrorEvent.IO_ERROR, function():void {
dispatchEvent(new Event("ioError"));
});
doTransactionRequest.addEventListener(Event.COMPLETE, function(event:Event):void
{
var response:XML = XML(doTransactionRequest.data);
if(response.localName() == "Exception") {
Alert.show(response.Message.toString());
} else if(response.localName() == "TransactionResult") {
// Disable listeners
removeListeners();
// Update id's
for each(var insertNode:XML in response.Inserted.children()) {
var id:String = insertNode.@id;
var clientId:String = insertNode.@clientId;
var localName:String = insertNode.localName();
var list:XMLList = (serverProps.descendants(localName)
+ layerProps.descendants(localName)
+ queryAspectProps.descendants(localName)
+ templateProps.descendants(localName)
+ reportProps.descendants(localName)
+ mapProps.descendants(localName)
+ guiConfigProps.descendants(localName)
+ contextProps.descendants(localName)).(@clientId == "true" && @id == clientId)
+ getProps(<{localName} clientId="true" id={clientId}/>);
for each(var item:XML in list) {
item.@id = id;
item.@clientId = "false";
item.@status = "existing";
}
}
// Reset status attributes
list = (serverProps.descendants()
+ layerProps.descendants()
+ queryAspectProps.descendants()
+ templateProps.descendants()
+ reportProps.descendants()
+ mapProps.descendants()
+ contextProps.descendants()
+ serverProps.source
+ layerProps.source
+ queryAspectProps.source
+ templateProps.source
+ reportProps.source
+ mapProps.source
+ contextProps.source
+ guiConfigProps.source).(attribute("status").length() > 0 && @status == "changed");
for each(item in list) {
item.@status = "existing";
}
// Remove deleted entities
var collections:Array = [serverProps, layerProps, queryAspectProps, templateProps, reportProps,
mapProps, contextProps, guiConfigProps];
for each(var collection:XMLListCollection in collections) {
for each(item in collection) {
if(item.@status == "deleted") {
collection.removeItemAt(collection.getItemIndex(item));
}
}
}
// Remove deleted references
for each(item in layerProps.source.descendants().(attribute("status").length() > 0 && @status == "deleted")) {
delete layerProps.source.descendants().(copy() == item)[0];
}
for each(item in mapProps.source.descendants().(attribute("status").length() > 0 && @status == "deleted")) {
delete mapProps.source.descendants().(copy() == item)[0];
}
for each(item in contextProps.source.descendants().(attribute("status").length() > 0 && @status == "deleted")) {
delete contextProps.source.descendants().(copy() == item)[0];
}
for each(item in guiConfigProps.source.descendants().(attribute("status").length() > 0 && @status == "deleted")) {
delete guiConfigProps.source.descendants().(copy() == item)[0];
}
// Rebuild trees
buildContextTree();
buildServerTree();
buildConfigTree();
// Re enable listeners
addListeners();
if(contextsUpdated) {
var contexts:Array = new Array();
for each(item in contextProps) {
contexts.push(item.Name.toString());
}
Application.application.dispatchEvent(new ConfigChangeEvent(ConfigChangeEvent.CONTEXTS_CHANGE,
contexts));
}
if(guiConfigsUpdated) {
var guiConfigs:Array = new Array();
for each(item in guiConfigProps) {
guiConfigs.push(item.@name.toString());
}
Application.application.dispatchEvent(new ConfigChangeEvent(ConfigChangeEvent.GUI_CONFIGS_CHANGE,
guiConfigs));
}
// Show alert
Alert.show("Inserted : " + response.Inserted.@count + "\n" +
"Updated : " + response.Updated.@count + "\n" +
"Deleted : " + response.Deleted.@count);
}
});
var request:URLRequest = new URLRequest(_serverUrl + "request=DoTransaction");
request.data = "" + transaction.toXMLString();
request.method = URLRequestMethod.POST;
request.contentType = "text/xml; charset=utf-8"
request.requestHeaders.push(new URLRequestHeader("Content-Encoding", "UTF-8"));
doTransactionRequest.load(request);
var doGUIConfigRequest:URLLoader = new URLLoader();
doGUIConfigRequest.addEventListener(IOErrorEvent.IO_ERROR, function():void {
dispatchEvent(new Event("ioError"));
});
}
public function hasChanges():Boolean {
return (XMLList(contextProps.source.Context.(@status != "existing"))
.length() > 0 ||
XMLList(serverProps.source.Server.(@status != "existing"))
.length() > 0 ||
XMLList(layerProps.source.Layer.(@status != "existing"))
.length() > 0 ||
XMLList(mapProps.source.Map.(@status != "existing"))
.length() > 0 ||
XMLList(templateProps.source.Template.(@status != "existing"))
.length() > 0 ||
XMLList(reportProps.source.Report.(@status != "existing"))
.length() > 0);
}
/*public function addCollectionsEventListener(listener:Function):void
{
}*/
private var clientCapabilities:Object = new Object();
private var serverCapabilities:Object = new Object();
private function doGetCapabilitiesRequest(server:XML, retServer:Server):void {
var serverProps:XML = getProps(server)[0];
var service:HTTPService = new HTTPService();
service.url = getCapabilitiesUrl(serverProps, retServer);
service.resultFormat = "e4x";
service.addEventListener(FaultEvent.FAULT, function(event:FaultEvent):void {
Alert.show(event.toString());
});
service.addEventListener(ResultEvent.RESULT, function():void {
var result:XMLList = XMLList(service.lastResult);
var serviceType:String = serverProps.Service.toString();
retServer.capabilities.source = result;
retServer.layers.source = getServerLayersFromResponse(
result, serviceType);
if(serviceType == "OGC:WFS") {
retServer.featureTypes.source = result.FeatureTypeList.FeatureType.copy();
for each(var type:XML in result.FeatureTypeList.FeatureType) {
var name:String = type.Name;
var uri:String = null;
if(name.indexOf(":") != -1) {
var prefix:String = name.split(":")[0];
name = name.split(":")[1];
uri = type.namespace(prefix);
}
var list:XMLListCollection =
retServer.getFeatureTypeAttributes(new QName(uri, name));
doDescribeFeatureRequest(serverProps, uri, name, list);
}
} else if(serviceType == "GI") {
retServer.featureTypes.source = result.FeatureTypesLocalWFSClient.FeatureType.copy();
for each(type in result.FeatureTypesLocalWFSClient.FeatureType) {
name = type.toString();
uri = null;
if(name.indexOf(":") != -1) {
prefix = name.split(":")[0];
name = name.split(":")[1];
uri = type.namespace(prefix);
}
list =
retServer.getFeatureTypeAttributes(new QName(uri, name));
doDescribeFeatureRequest(serverProps, uri, name, list);
}
}
retServer.featureTypesEmptyItem.source =
+ retServer.featureTypes.source.copy();
if(serviceType == "GI") {
for each(var layer:XML in retServer.capabilities.source.Layer) {
name = layer.FeatureType;
uri = null;
if(name.indexOf(":") != -1) {
prefix = name.split(":")[0];
name = name.split(":")[1];
uri = layer.FeatureType.namespace(prefix);
}
list = retServer.getLayerFeatureTypeAttributes(layer.Name.toString());
doDescribeFeatureRequest(serverProps, uri, name, list);
retServer.layerFeatureTypes[layer.Name] = layer.FeatureType[0];
}
}
});
service.send();
}
private function getCapabilities(server:XML, forceLoad:Boolean = false):Server {
if(server == null || server.attribute("id").length() == 0 ||
server.attribute("clientId").length() == 0) {
return new Server();
}
var serverProps:XML = getProps(server);
if(serverProps.@brief == 'true') {
return new Server();
}
var clientId:Boolean = server.@clientId == "true";
var retServer:Server;
if(!forceLoad) {
retServer = clientId ?
clientCapabilities["" + server.@id] :
serverCapabilities["" + server.@id];
if(retServer != null) {
return retServer;
}
}
retServer = new Server();
if(clientId) {
clientCapabilities["" + server.@id] = retServer;
} else {
serverCapabilities["" + server.@id] = retServer;
}
if(serverProps.child("Security").length() > 0
&& serverProps.Security != "none"
&& XML(serverProps.Security[0]).children().length() != 0) {
var serverLoginPanel:ServerLoginPanel = new ServerLoginPanel();
PopUpManager.addPopUp(serverLoginPanel, DisplayObject(Application.application), true);
BindingUtils.bindProperty(serverLoginPanel, "maxHeight", Application.application, "height");
BindingUtils.bindProperty(serverLoginPanel, "maxWidth", Application.application, "width");
BindingUtils.bindSetter(function():void {
PopUpManager.centerPopUp(serverLoginPanel);
}, mx.core.Application.application, "height");
BindingUtils.bindSetter(function():void {
PopUpManager.centerPopUp(serverLoginPanel);
}, mx.core.Application.application, "width");
PopUpManager.centerPopUp(serverLoginPanel);
serverLoginPanel.loginHeading = serverProps.Title;
serverLoginPanel.addEventListener(LoginEvent.LOGIN,
function(event:LoginEvent):void {
PopUpManager.removePopUp(serverLoginPanel);
retServer.user = event.login;
retServer.password = event.password;
doGetCapabilitiesRequest(serverProps, retServer);
});
} else {
doGetCapabilitiesRequest(serverProps, retServer);
}
return retServer;
}
public function getServerLayers(server:XML, forceLoad:Boolean = false):XMLListCollection {
return getCapabilities(server, forceLoad).layers;
}
public function getFeatureTypes(server:XML, forceLoad:Boolean = false, emptyItem:Boolean = true):XMLListCollection {
if(emptyItem) {
return getCapabilities(server, forceLoad).featureTypesEmptyItem;
} else {
return getCapabilities(server, forceLoad).featureTypes;
}
}
public function getFeatureTypeAttributes(server:XML, featureType:XML, forceLoad:Boolean = false):XMLListCollection {
if(featureType == null || server == null) {
return null;
}
var serverProps:XML = getProps(server)[0];
var name:String = null;
if(serverProps.Service == "OGC:WFS") {
name = featureType.Name;
} else if(serverProps.Service == "GI") {
name = featureType.children()[0];
}
var uri:String = null;
if(name.indexOf(":") != -1) {
uri = featureType.namespace(name.split(":")[0]);
name = name.split(":")[1];
}
var serverObj:Server = getCapabilities(server, forceLoad);
return serverObj.getFeatureTypeAttributes(new QName(uri, name), forceLoad);
}
private function getCapabilitiesUrl(server:XML, retServer:Server):String {
var url:String = "";
switch(server.Service.toString()) {
case "GI":
url = server.Onlineresource.toString() + "request=GetCapabilities";
break;
case "OGC:WMS":
url = server.Onlineresource.toString() + "service=WMS&request=GetCapabilities&version=" + server.Version.toString();
break;
case "OGC:WFS":
url = server.Onlineresource.toString() + "service=WFS&request=GetCapabilities&version=" + server.Version.toString();
}
if(server.child("Proxy").length() > 0
&& server.Proxy.toString() == "t") {
url = this._proxyServerUrl + "/"
+ url.split("//")[1];
}
if(server.child("Security").length() > 0) {
switch(server.Security.toString()) {
case "ows":
url += "&user=" + retServer.user + "&password=" + retServer.password;
}
}
return url;
}
private function removeNameless(layers:XMLList):XMLList {
return layers.(child("Name").length() > 0);
}
private function flattenLayerList(rootLayer:XML):XMLList {
var list:XMLList = new XMLList();
XML(list[0]).appendChild(rootLayer.copy()[0]);
var subLayers:XMLList = rootLayer.Layer.copy();
delete list.Layer.Layer;
for each(var layer:XML in subLayers) {
for each(var subLayer:XML in flattenLayerList(layer)) {
XML(list[0]).appendChild(subLayer);
}
}
return list.children();
}
private function getServerLayersFromResponse(serverResponse:XMLList, service:String):XMLList {
switch(service) {
case "GI":
return serverResponse.Layer;
case "OGC:WMS":
return removeNameless(
flattenLayerList(serverResponse.Capability.Layer[0]));
}
return null;
}
private function getFeatureTypeNamesFromResponse(serverResponse:XMLList, server:XML):Array {
var names:Array = new Array();
var serviceType:String = server.Service;
if(serviceType == "OGC:WFS") {
for each(var type:XML in serverResponse.FeatureTypeList.FeatureType) {
var name:String = type.Name;
var uri:String = null;
if(name.indexOf(":") != -1) {
var prefix:String = name.split(":")[0];
name = name.split(":")[1];
uri = type.namespace(prefix);
}
var list:XMLListCollection = new XMLListCollection();
doDescribeFeatureRequest(server, uri, name, list);
names.push([new QName(uri, name), list]);
}
} else if(serviceType == "GI") {
}
return names;
}
private function doDescribeFeatureRequest(server:XML, uri:String, name:String, list:XMLListCollection):void {
var service:HTTPService = new HTTPService();
service.url = server.Onlineresource.toString() + "service=WFS&version=1.1.0&request=DescribeFeatureType"
+ "&typeName=" + (uri ? "pref:" : "") + name;
if(uri != null) {
service.url += "&namespace=xmlns(" +
"pref=" + uri + ")";
}
service.resultFormat = "e4x";
service.addEventListener(ResultEvent.RESULT, function(event:ResultEvent):void
{
var result:XMLList = XMLList(service.lastResult);
var typeName:String = result.element.(@name == name).@type;
var prefix:String = "";
var nspace:String = "";
if(typeName.indexOf(":") != -1) {
var parts:Array = typeName.split(":");
if(result.namespace(parts[0]) == result.@targetNamespace) {
typeName = parts[1];
}
prefix = parts[0];
nspace = parts[1];
}
var complexType:XMLList = result.complexType.(@name == typeName);
var elements:XMLList = new XMLList();
elements.elements += complexType..element;
elements.@prefix = prefix;
elements.@nspace = nspace;
list.source = elements.element;
});
service.send();
}
public function getLayerFeatureTypeAttributes(server:XML, layer:QName, forceLoad:Boolean = false):XMLListCollection {
if(server.Service.toString() == "OGC:WFS") {
return getCapabilities(server, forceLoad).getFeatureTypeAttributes(layer, forceLoad);
} else {
return getCapabilities(server, forceLoad).getLayerFeatureTypeAttributes(layer.localName);
}
}
public function getFeatureTypeForQueryLayer(layer:XML, server:XML, forceLoad:Boolean = false):XML {
var serverProps:XML = getProps(server)[0];
if(serverProps.Service == "OGC:WFS") {
return layer;
} else if(serverProps.Service == "GI") {
return getCapabilities(server, forceLoad).layerFeatureTypes[layer.Name];
}
return null;
}
public function getQueryLayers(server:XML, forceLoad:Boolean = false):XMLListCollection {
if(server == null) {
return null;
}
var serverProps:XML = getProps(server)[0];
if(serverProps.Service == "GI") {
return getServerLayers(server, forceLoad);
} else if(serverProps.Service == "OGC:WFS") {
return getFeatureTypes(server, forceLoad, false);
}
return null;
}
private function getServerVersion(version:XMLList, position:Number):Number {
var str:String = version.toString();
var index:Number = -1;
for(var i:Number = 0; i < position; i++) {
index = str.indexOf(".", index + 1);
}
var end:Number = str.indexOf(".", index + 1);
if(end == -1) {
str = str.substr(index + 1);
} else {
str = str.substring(index + 1, end);
}
return Number(str);
}
public function getTransformationServers():XMLList {
return serverProps.source.(Service == "GI")
.(getServerVersion(Version, 0) == 3);
}
public function getMapServers():XMLList {
return serverProps.source
.(Service == "GI"
|| Service == "OGC:WMS");
}
public function getQueryServers(omitWfs:Boolean = false):XMLList {
return serverProps.source
.(Service == "GI"
|| (Service == "OGC:WFS" && !omitWfs));
}
public function getFeatureServers():XMLList {
return serverProps.source
.(Service == "OGC:WFS");
}
public function supportsFormats(server:XML):Boolean {
return getProps(server).Service == "OGC:WMS";
}
public function supportsSelections(server:XML):Boolean {
return getProps(server).Service == "GI";
}
public function isUnique(type:String, name:String, newElement:Boolean = false):Boolean {
var count:Number = newElement ? 0 : 1;
switch(type)
{
case 'Context':
return XMLList(contextProps.source.(Name == name)).length() == count;
break;
case 'Layer':
return XMLList(layerProps.source.(Name == name)).length() == count;
break;
case 'QueryAspect':
return XMLList(queryAspectProps.source.(Name == name)).length() == count;
break;
case 'Template':
return XMLList(templateProps.source.(Name == name)).length() == count;
break
case 'Map':
return XMLList(mapProps.source.(Name == name)).length() == count;
}
return true;
}
public function getUnusedLayers(map:XML):XMLList {
var list:XMLList = layerProps.source.copy();
var usedLayers:XMLList = this.getLayers(map).copy();
for(var i:Number = 0; i < list.length(); i++) {
for each(var currentLayer:XML in usedLayers) {
if(currentLayer.@clientId == list[i].@clientId
&& currentLayer.@id == list[i].@id) {
delete list[i];
i--;
}
}
}
return list;
}
public function getUnusedMaps(context:XML):XMLList {
var list:XMLList = mapProps.source.copy();
var usedMaps:XMLList = this.getMaps(context).copy();
for(var i:Number = 0; i < list.length(); i++) {
for each(var currentMap:XML in usedMaps) {
if(currentMap.@clientId == list[i].@clientId
&& currentMap.@id == list[i].@id) {
delete list[i];
i--;
}
}
}
return list;
}
public function getUnusedQueryAspects(map:XML):XMLList {
var list:XMLList = queryAspectProps.source.copy();
var usedQueryAspects:XMLList = this.getQueryAspects(map).copy();
for(var i:Number = 0; i < list.length(); i++) {
for each(var currentQueryAspect:XML in usedQueryAspects) {
if(currentQueryAspect.@clientId == list[i].@clientId
&& currentQueryAspect.@id == list[i].@id) {
delete list[i];
i--;
}
}
}
return list;
}
public function getUnusedTemplates(map:XML):XMLList {
var list:XMLList = templateProps.source.copy();
var usedTemplates:XMLList = this.getTemplates(map).copy();
for(var i:Number = 0; i < list.length(); i++) {
for each(var currentTemplate:XML in usedTemplates) {
if(currentTemplate.@clientId == list[i].@clientId
&& currentTemplate.@id == list[i].@id) {
delete list[i];
i--;
}
}
}
return list;
}
public function dropServerCache(server:XML):void {
var clientId:Boolean = false;
if(server.child("@clientId").length() > 0) {
clientId = server.@clientId == "true";
}
if(clientId) {
clientCapabilities["" + server.@id] = null;
} else {
serverCapabilities["" + server.@id] = null;
}
//dispatchEvent(new Event("serverCacheDropped"));
}
public function isServerUsed(server:XML):Boolean {
if(server.localName() != "Server") {
return false;
}
var clientId:Boolean = false;
if(server.attribute("clientId").length() > 0) {
clientId = server.@clientId.toString().toLowerCase() == "true";
}
for each(var currentServer:XML in layerProps.source..Server) {
var currentClientId:Boolean = false;
if(currentServer.attribute("clientId").length() > 0) {
currentClientId = currentServer.@clientId.toString().toLowerCase() == "true";
}
if(currentClientId == clientId
&& currentServer.@id == server.@id) {
return true;
}
}
for each(currentServer in layerProps.source..Featureserver) {
currentClientId = false;
if(currentServer.attribute("clientId").length() > 0) {
currentClientId = currentServer.@clientId.toString().toLowerCase() == "true";
}
if(currentClientId == clientId
&& currentServer.@id == server.@id) {
return true;
}
}
for each(currentServer in queryAspectProps.source..Server) {
currentClientId = false;
if(currentServer.attribute("clientId").length() > 0) {
currentClientId = currentServer.@clientId.toString().toLowerCase() == "true";
}
if(currentClientId == clientId
&& currentServer.@id == server.@id) {
return true;
}
}
for each(currentServer in contextProps.source..Server) {
currentClientId = false;
if(currentServer.attribute("clientId").length() > 0) {
currentClientId = currentServer.@clientId.toString().toLowerCase() == "true";
}
if(currentClientId == clientId
&& currentServer.@id == server.@id) {
return true;
}
}
return false;
}
public function treeToProps(tree:XML, disableListeners:Boolean = false):void {
// Disable listeners
if(disableListeners) {
removeListeners();
}
if(tree.localName() == "Contexts") {
for each(var map:XML in tree..Map) {
var currentRef:XML = newRef(map);
if(map != currentRef) {
var props:XML = getProps(map);
var mapLayerChilds:XMLList = new XMLList();
for each(var mapLayer:XML in map.Layers.Layer) {
mapLayerChilds += newRef(mapLayer, false);
}
XML(props.Layers[0]).setChildren(mapLayerChilds);
// TODO: drag and drop between maps allowed??
/*XML(props.Templates[0]).setChildren(map.Templates.Template);
XML(props.QueryAspects[0]).setChildren(map.QueryAspects.QueryAspect);
XML(props.Reports[0]).setChildren(map.Reports.Report);*/
for each(var layer:XML in map.Layers..Layer.(getProps(copy()).Type.toString() == "Group")) {
var layerProps:XML = getProps(layer);
var layerChilds:XMLList = new XMLList();
for each(var subLayer:XML in layer.children()) {
layerChilds += newRef(subLayer, false);
}
if(layerChilds != layerProps.Layers.Layer) {
XML(layerProps.Layers[0]).setChildren(layerChilds);
if(layerProps.@status != "new") {
layerProps.@status = "changed";
}
}
}
if(props.@status != "new") {
props.@status = "changed";
}
}
}
}
// Re enable listeners
if(disableListeners) {
addListeners();
}
}
// Copy content of contextTree to entities (used for dragging)
public function updateEntity(item:XML, disableListeners:Boolean = false):void {
// Disable listeners
if(disableListeners) {
removeListeners();
}
var groupName:String = item.localName();
if(groupName == "Layer") {
groupName = "Layers";
}
var items:XMLList = new XMLList();
for each(var currentItem:XML in item.children()) {
items += newRef(currentItem, false);
}
var parentNode:XML = getParentEntity(item);
if(parentNode != null) {
XML(parentNode.child(groupName)).setChildren(items);
if(parentNode.@status != "new") {
parentNode.@status = "changed";
}
}
// Re enable listeners
if(disableListeners) {
addListeners();
}
}
}
}