commit d750eeca8af9074fe458739a1d3cf341880a2c7e Author: thkim Date: Tue Oct 21 10:11:23 2025 +0900 Init diff --git a/.classpath_sample b/.classpath_sample new file mode 100644 index 0000000..047992d --- /dev/null +++ b/.classpath_sample @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.euml2 b/.euml2 new file mode 100644 index 0000000..e348ac9 --- /dev/null +++ b/.euml2 @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch b/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch new file mode 100644 index 0000000..627021f --- /dev/null +++ b/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..308d5b5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,88 @@ +/target +.DS_Store +._.DS_Store +**/.DS_Store +**/._.DS_Store + + +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### STS ### +.apt_generated +.classpath +.factorypath +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + + +# Scala IDE specific (Scala & Java development for Eclipse) +.cache-main +.scala_dependencies +.worksheet + +# Uncomment this line if you wish to ignore the project description file. +# Typically, this file would be tracked if it contains build/dependency configurations: +#.project + +.svn + +# ---> Java +# Compiled class file +#*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +replay_pid* + + +### VS Code ### +.vscode/ +.vs/ + + +# Added by thkim +.classpath +/src/main/resources/egovframework/egovProps/globals.properties +/src/main/webapp/WEB-INF/clipreport4/DataConnection.properties \ No newline at end of file diff --git a/.project b/.project new file mode 100644 index 0000000..ef976b1 --- /dev/null +++ b/.project @@ -0,0 +1,71 @@ + + + map + @key 32303037303533312D31302067656F696E666F5F65476F762F544B + + + + + org.eclipse.ui.externaltools.ExternalToolBuilder + full,incremental, + + + LaunchConfigHandle + <project>/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.springframework.ide.eclipse.core.springbuilder + + + + + com.soyatec.additional.Builder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.m2e.core.maven2Nature + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.jdt.core.javanature + org.springframework.ide.eclipse.core.springnature + egovframework.dev.imp.ide.natures.egovnature + org.eclipse.wst.jsdt.core.jsNature + com.soyatec.additional.Nature + + + + 1750384324665 + + 30 + + org.eclipse.core.resources.regexFilterMatcher + node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ + + + + diff --git a/.project_sample b/.project_sample new file mode 100644 index 0000000..c544f37 --- /dev/null +++ b/.project_sample @@ -0,0 +1,60 @@ + + + map + @key 32303037303533312D31302067656F696E666F5F65476F762F544B + + + + + org.eclipse.ui.externaltools.ExternalToolBuilder + full,incremental, + + + LaunchConfigHandle + <project>/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.springframework.ide.eclipse.core.springbuilder + + + + + com.soyatec.additional.Builder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.m2e.core.maven2Nature + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.jdt.core.javanature + org.springframework.ide.eclipse.core.springnature + egovframework.dev.imp.ide.natures.egovnature + org.eclipse.wst.jsdt.core.jsNature + com.soyatec.additional.Nature + + diff --git a/.umlproject b/.umlproject new file mode 100644 index 0000000..e348ac9 --- /dev/null +++ b/.umlproject @@ -0,0 +1,7 @@ + + + + + + + diff --git a/apply.bat b/apply.bat new file mode 100644 index 0000000..60c1cf8 --- /dev/null +++ b/apply.bat @@ -0,0 +1,80 @@ +@echo off +setlocal enabledelayedexpansion + +set source_prefix=src\main\webapp\ +set target_prefix=C:\Users\dbnt\eclipse-workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\geoinfo_eGov_work\ +set target_directory=C:\Users\dbnt\git\dbnt\geoinfo.or.kr\geoinfo_eGov_work\ + +set source_file= +set target_file= + +for /f "delims=" %%i in (list.txt) do ( + + echo %%i | findstr /v "^#" > nul + if !errorlevel! == 0 ( + set "line=%%i" + rem # ʴ ó + echo !line! + + + set line=%%i + + if "!line:~-5!" == ".java" ( + echo Skip + ) else if "!line:~-4!" == ".xml" ( + set source_file=%target_directory%!line! + set relative_path=!line:%source_prefix%=! + :: "src\main\resources\" + set relative_path=!relative_path:*src\main\resources\=! + set target_file=%target_prefix%WEB-INF\classes\!relative_path! + ) else if "!line:~-4!" == ".jsp" ( + set source_file=%target_directory%!line! + set relative_path=!line:%source_prefix%=! + set target_file=%target_prefix%!relative_path! + ) else if "!line:~-4!" == ".css" ( + set source_file=%target_directory%!line! + set relative_path=!line:%source_prefix%=! + set target_file=%target_prefix%!relative_path! + ) else if "!line:~-4!" == ".png" ( + set source_file=%target_directory%!line! + set relative_path=!line:%source_prefix%=! + set target_file=%target_prefix%!relative_path! + ) else if "!line:~-4!" == ".svg" ( + set source_file=%target_directory%!line! + set relative_path=!line:%source_prefix%=! + set target_file=%target_prefix%!relative_path! + ) else if "!line:~-3!" == ".js" ( + set source_file=%target_directory%!line! + set relative_path=!line:%source_prefix%=! + set target_file=%target_prefix%!relative_path! + ) else if "!line:~-4!" == ".reb" ( + set source_file=%target_directory%!line! + set relative_path=!line:%source_prefix%=! + set target_file=%target_prefix%!relative_path! + ) else if "!line:~-6!" == ".woff2" ( + set source_file=%target_directory%!line! + set relative_path=!line:%source_prefix%=! + set target_file=%target_prefix%!relative_path! + ) else if "!line:~-5!" == ".woff" ( + set source_file=%target_directory%!line! + set relative_path=!line:%source_prefix%=! + set target_file=%target_prefix%!relative_path! + ) else if "!line:~-4!" == ".otf" ( + set source_file=%target_directory%!line! + set relative_path=!line:%source_prefix%=! + set target_file=%target_prefix%!relative_path! + ) else if "!line:~-11!" == ".properties" ( + set source_file=%target_directory%!line! + set relative_path=!line:%source_prefix%=! + set target_file=%target_prefix%!relative_path! + ) + + rem Copy the source file to the target location, overwriting if necessary + echo Copying "!source_file!" to "!target_file!" + xcopy /i /Y "!source_file!" "!target_file!" + ) else ( + echo # õ˴ϴ + ) + + +) \ No newline at end of file diff --git a/doc/Untitled Project.IAB b/doc/Untitled Project.IAB new file mode 100644 index 0000000..fbcbacf Binary files /dev/null and b/doc/Untitled Project.IAB differ diff --git a/doc/Untitled Project.IAD b/doc/Untitled Project.IAD new file mode 100644 index 0000000..8b1865c Binary files /dev/null and b/doc/Untitled Project.IAD differ diff --git a/doc/Untitled Project.IMB b/doc/Untitled Project.IMB new file mode 100644 index 0000000..811c7a2 Binary files /dev/null and b/doc/Untitled Project.IMB differ diff --git a/doc/Untitled Project.IMD b/doc/Untitled Project.IMD new file mode 100644 index 0000000..49026aa Binary files /dev/null and b/doc/Untitled Project.IMD differ diff --git a/doc/Untitled Project.PFI b/doc/Untitled Project.PFI new file mode 100644 index 0000000..46e5860 Binary files /dev/null and b/doc/Untitled Project.PFI differ diff --git a/doc/Untitled Project.PO b/doc/Untitled Project.PO new file mode 100644 index 0000000..173e320 Binary files /dev/null and b/doc/Untitled Project.PO differ diff --git a/doc/Untitled Project.PR b/doc/Untitled Project.PR new file mode 100644 index 0000000..96261a5 Binary files /dev/null and b/doc/Untitled Project.PR differ diff --git a/doc/Untitled Project.PRI b/doc/Untitled Project.PRI new file mode 100644 index 0000000..9d8636a Binary files /dev/null and b/doc/Untitled Project.PRI differ diff --git a/doc/Untitled Project.PS b/doc/Untitled Project.PS new file mode 100644 index 0000000..039e837 Binary files /dev/null and b/doc/Untitled Project.PS differ diff --git a/doc/Untitled Project.SearchResults b/doc/Untitled Project.SearchResults new file mode 100644 index 0000000..96a9dd3 --- /dev/null +++ b/doc/Untitled Project.SearchResults @@ -0,0 +1,5 @@ +---- selectApproveLogCnt Matches (4 in 4 files) ---- +DownloadAppMapper.java (d:\egov_geoinfo\egovframedev-3.5.1-64bit\workspace\geoinfo_admin\src\main\java\geoinfo\admins\chlog\service): public EgovMap selectApproveLogCnt(String userId) throws Exception; +DownloadAppServiceImpl.java (d:\egov_geoinfo\egovframedev-3.5.1-64bit\workspace\geoinfo_admin\src\main\java\geoinfo\admins\chlog\service\impl): EgovMap map = masterMapper.selectApproveLogCnt((String)params.get("userid")); +DownloadApp_SQL.xml (d:\egov_geoinfo\egovframedev-3.5.1-64bit\workspace\geoinfo_admin\src\main\resources\geoinfo\sqlmap\mappers\admins\chlog): diff --git a/doc/Untitled Project.WK3 b/doc/Untitled Project.WK3 new file mode 100644 index 0000000..919e5f8 Binary files /dev/null and b/doc/Untitled Project.WK3 differ diff --git a/doc/eGov.ucd b/doc/eGov.ucd new file mode 100644 index 0000000..0e39a9d --- /dev/null +++ b/doc/eGov.ucd @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/doc/geoinfo.com.ucd b/doc/geoinfo.com.ucd new file mode 100644 index 0000000..0e39a9d --- /dev/null +++ b/doc/geoinfo.com.ucd @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/doc/javadoc.xml b/doc/javadoc.xml new file mode 100644 index 0000000..70f4a66 --- /dev/null +++ b/doc/javadoc.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/list.txt b/list.txt new file mode 100644 index 0000000..9c55ee4 --- /dev/null +++ b/list.txt @@ -0,0 +1,15 @@ +#src\main\resources\egovframework\egovProps\globals.properties +#src\main\java\geoinfo\regi\manageList\ManageExcelUploadProc01Controller.java +#src\main\webapp\WEB-INF\views\web\input\excel_step00.jsp +#src\main\webapp\WEB-INF\views\web\input\excel_step31.jsp +#src\main\webapp\com\css\common.v2.0.css +#src\main\webapp\com\css\common.v2.0.css.map +#src\main\webapp\WEB-INF\views\web\manage\list_reg.jsp + +src\main\webapp\WEB-INF\views\drilling\inquiry\drilling_inquiry_project.jsp +src\main\webapp\js\map\main\map.js +src\main\webapp\js\map\main\left\left.js +src\main\webapp\js\map\main\left\left_new.js +src\main\resources\egovframework\sqlmap\mapper\map\MapLeft_SQL.xml + +src\main\resources\egovframework\sqlmap\mapper\drilling\home\DrillingHomeMapper.xml diff --git a/open_builded.bat b/open_builded.bat new file mode 100644 index 0000000..7c4e934 --- /dev/null +++ b/open_builded.bat @@ -0,0 +1 @@ +explorer C:\Users\dbnt\eclipse-workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\geoinfo_eGov_work diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..fbda388 --- /dev/null +++ b/pom.xml @@ -0,0 +1,595 @@ + + + 4.0.0 + myMap + myMap + war + 1.0.0 + myMap + http://www.egovframe.go.kr + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + + + + + 1.7 + + 3.2.4.RELEASE + 1.7.3 + + 1.6.6 + + 3.0.3 + + 3.5.0 + + 11.0 + 1.13 + + UTF-8 + UTF-8 + + + + + central + https://repo.maven.apache.org/maven2/ + + true + + + false + + + + + eclipse-oxygen-releases + Eclipse Oxygen Releases + https://repo.eclipse.org/content/repositories/oxygen-releases/ + + true + + + false + + + + eclipse-neon-releases + Eclipse Neon Releases + https://repo.eclipse.org/content/repositories/neon-releases/ + + true + + + false + + + + + osgeo + OSGeo Release Repository + https://repo.osgeo.org/repository/release/ false + true + + + + jaspersoft-repo + https://jaspersoft.jfrog.io/jaspersoft/third-party-ce-artifacts/ + + true + + + false + + + + + egovframe + http://maven.egovframe.go.kr/maven/ + + true + + + false + + + + + + + + org.springframework + spring-context + ${org.springframework-version} + + + commons-logging + commons-logging + + + + + org.springframework + spring-web + ${org.springframework-version} + + + org.springframework + spring-webmvc + ${org.springframework-version} + + + org.springframework + spring-aop + ${org.springframework-version} + + + org.springframework + spring-beans + ${org.springframework-version} + + + org.springframework + spring-context-support + ${org.springframework-version} + + + org.springframework + spring-core + ${org.springframework-version} + + + org.springframework + spring-jdbc + ${org.springframework-version} + + + org.springframework + spring-tx + ${org.springframework-version} + + + org.springframework + spring-websocket + 4.1.2.RELEASE + + + + aopalliance + aopalliance + 1.0 + + + org.mybatis + mybatis + 3.2.2 + + + org.mybatis + mybatis-spring + 1.2.0 + + + org.apache.tomcat + tomcat-dbcp + provided + 7.0.53 + + + commons-dbcp + commons-dbcp + 1.4 + + + mysql + mysql-connector-java + 5.1.31 + + + postgresql + postgresql + 9.1-901.jdbc4 + + + org.aspectj + aspectjrt + ${org.aspectj-version} + + + org.aspectj + aspectjweaver + ${org.aspectj-version} + + + org.aspectj + aspectjtools + ${org.aspectj-version} + + + + javax.servlet + servlet-api + provided + 2.5 + + + javax.servlet.jsp + jsp-api + provided + 2.1 + + + javax.servlet + jstl + 1.2 + + + javax.annotation + jsr250-api + 1.0 + + + javax.inject + javax.inject + 1 + + + javax.websocket + javax.websocket-api + 1.0 + provided + + + + org.slf4j + slf4j-api + ${org.slf4j-version} + + + org.slf4j + jcl-over-slf4j + ${org.slf4j-version} + + + org.slf4j + slf4j-log4j12 + ${org.slf4j-version} + + + log4j + log4j + 1.2.17 + + + javax.mail + mail + + + javax.jms + jms + + + com.sun.jdmk + jmxtools + + + com.sun.jmx + jmxri + + + + + org.lazyluke + log4jdbc-remix + 0.2.7 + + + + org.codehaus.jackson + jackson-mapper-asl + 1.9.13 + + + org.codehaus.jackson + jackson-core-asl + 1.9.13 + + + org.json + json + 20180813 + + + com.googlecode.json-simple + json-simple + 1.1.1 + + + + commons-io + commons-io + 2.0.1 + + + commons-fileupload + commons-fileupload + 1.2.2 + + + commons-codec + commons-codec + 1.10 + + + com.jfinal + cos + 26Dec2008 + + + + org.apache.tiles + tiles-jsp + ${org.apache.tiles.version} + + + org.apache.tiles + tiles-core + ${org.apache.tiles.version} + + + net.sf.jasperreports + jasperreports + 5.1.0 + + + org.jdom + jdom + 2.0.2 + + + com.navercorp.lucy + lucy-xss-servlet + 2.0.0 + + + org.projectlombok + lombok + 1.18.12 + provided + + + com.lowagie + itext + 2.1.7.js2 + + + io.jsonwebtoken + jjwt + 0.9.1 + + + xml-apis + xml-apis + 1.0.b2 + + + org.jdom + jdom + 1.1.3 + + + junit + junit + 4.4 + + + postgresql + postgresql + 8.4-701.jdbc3 + + + commons-codec + commons-codec + 1.2 + + + commons-io + commons-io + 2.1 + + + mysql + mysql-connector-java + 5.1.17 + + + com.googlecode.json-simple + json-simple + 1.1 + + + org.geotools + gt-main + ${geotools.version} + + + org.geotools + gt-opengis + ${geotools.version} + + org.geotools + gt-referencing + ${geotools.version} + + org.geotools + gt-epsg-hsql + ${geotools.version} + + org.geotools + gt-cql + ${geotools.version} + + + org.geotools + gt-data + ${geotools.version} + + + org.geotools + gt-api + ${geotools.version} + + + org.geotools + gt-metadata + ${geotools.version} + + + org.geotools + gt-xml + ${geotools.version} + + + org.geotools + gt-swing + ${geotools.version} + + + org.geotools + gt-render + ${geotools.version} + + + org.geotools + gt-shapefile + ${geotools.version} + + + org.geotools.xsd + gt-xsd-sld + ${geotools.version} + + + org.geotools + gt-geojson + ${geotools.version} + + + org.geotools + gt-process + ${geotools.version} + + + org.geotools + gt-jdbc + ${geotools.version} + + + org.geotools.jdbc + gt-jdbc-postgis + ${geotools.version} + + + org.geotools.jdbc + gt-jdbc-oracle + ${geotools.version} + + + org.geotools.jdbc + gt-jdbc-h2 + ${geotools.version} + + + org.geotools.jdbc + gt-jdbc-mysql + ${geotools.version} + + + org.geotools.jdbc + gt-jdbc-db2 + ${geotools.version} + + + org.geotools.jdbc + gt-jdbc-sqlserver + ${geotools.version} + + + com.vividsolutions + jts + ${jts.version} + + + org.geotools + gt-wms + ${geotools.version} + + + org.eclipse.emf + org.eclipse.emf.ecore + 2.9.1-v20130827-0309 + + + + + + install + ${project.basedir}/target myMap + + + org.apache.maven.plugins + maven-war-plugin + 2.3 + + false + + + + + maven-eclipse-plugin + 2.9 + + + org.springframework.ide.eclipse.core.springnature + + + org.springframework.ide.eclipse.core.springbuilder + + true + true + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.5.1 + + ${java-version} + ${java-version} + ${project.build.sourceEncoding} -Xlint:all + true + true + + + + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + org.test.int1.Main + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.5 + + + + \ No newline at end of file diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 0000000..ed3ffc1 --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,19 @@ +# must be unique in a given SonarQube instance +sonar.projectKey=geoinfo + +# --- optional properties --- +sonar.host.url=http://localhost:9000 +# defaults to project key +#sonar.projectName=My project +# defaults to 'not provided' +#sonar.projectVersion=1.0 + +# Path is relative to the sonar-project.properties file. Defaults to . +#sonar.sources=. +sonar.sources=src/main/java,src/main/webapp +sonar.exclusions=**/kendo-ui/**/*, **/ClipReport4/**/*, **/G-PIN/**/*, **/IPIN/**/* +sonar.java.binaries=target/classes +sonar.scm.exclusions.disabled=true +# Encoding of the source code. Default is default system encoding +sonar.sourceEncoding=euc-kr +sonar.login=sqp_ab637361cfede0396764c018ea44c4f6773f858a \ No newline at end of file diff --git a/src/main/java/com/geotwo/webserver/core/ServerContext.java b/src/main/java/com/geotwo/webserver/core/ServerContext.java new file mode 100644 index 0000000..144186d --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/ServerContext.java @@ -0,0 +1,435 @@ +package com.geotwo.webserver.core; + +import com.geotwo.webserver.core.cache.ImgCacheMngr; +import com.geotwo.webserver.core.coverage.O2DemLayerMngr; +import com.geotwo.webserver.core.coverage.O2ImgLayerMngr; +import com.geotwo.webserver.core.coverage.WpsCovStoreMngr; +import com.geotwo.webserver.core.init.ServerConfiguration; +import com.geotwo.webserver.core.log.LogMngr; +import com.geotwo.webserver.core.map.Map; +import com.geotwo.webserver.core.map.layer.FeatureLayer; +import com.geotwo.webserver.core.map.layer.Layer; +import com.geotwo.webserver.core.map.layer.O2DemLayer; +import com.geotwo.webserver.core.tile.tms.TMSMngr; +import com.geotwo.webserver.core.tile.wmts.WMTSMngr; +import com.geotwo.webserver.core.util.ServerUtil; +import com.geotwo.webserver.core.vector.GWaveStoreMngr; +import com.geotwo.webserver.core.vector.JdbcStoreMngr; +import com.geotwo.webserver.core.vector.ShpStoreMngr; +import com.geotwo.webserver.core.vector.WpsVecStoreMngr; +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashSet; + +public class ServerContext { + private static Map serviceMap; + + private static String CONF_FOLDER_NAME = "/conf"; + + private static File confFolder = null; + + private static String STYLES_FOLDER_NAME = "/styles"; + + private static File stylesFolder; + + private static String PLUGINS_FOLDER_NAME = "/plugins"; + + private static File pluginsFolder; + + private static Integer docIndent = null; + + private static Boolean useNSPrefix = null; + + private static Integer defaultMaxFeatures = null; + + private static Boolean encryption = null; + + public static void initMap(String mapName, String nameSpace) throws Exception { + if (ServerUtil.isNullString(mapName)) { + LogMngr.getInstance().logError("[DB]", + "ServiceMap Name is NULL. Now set default [O2MAP]."); + mapName = "O2MAP"; + } + serviceMap = new Map(mapName, nameSpace); + } + + public static void changeMap(String mapName, String nameSpace) throws Exception { + if (ServerUtil.isNullString(mapName)) + throw new NullPointerException("Parameter [ServiceMap] is NULL"); + LogMngr.getInstance().logDebug("[MAP]", "Get MapList"); + HashSet mapList = ServerConfiguration.getInstance().getMapList(); + if (!mapList.contains(mapName.trim().toUpperCase())) + throw new NullPointerException("Parameter [ServiceMap:" + mapName + "] is not exist in ServiceMap List."); + if (ServerUtil.isNullString(nameSpace)) + nameSpace = serviceMap.getNameSpaceURI(); + if (serviceMap.getName().equalsIgnoreCase(mapName) && + serviceMap.getNameSpaceURI().equalsIgnoreCase(nameSpace)) + throw new IllegalArgumentException("Parameter [ServiceMap:" + mapName + "] is current Map."); + Map dirtyMap = null; + try { + ServerInfo.getInstance().setReStarting(true); + dirtyMap = serviceMap; + serviceMap = new Map(mapName, nameSpace); + LogMngr.getInstance().logInfo("[LAYER]", "-----------------------------------"); + LogMngr.getInstance().logInfo("[LAYER]", "Create Service Layer"); + LogMngr.getInstance().logInfo("[LAYER]", "-----------------------------------"); + initLayers(); + LogMngr.getInstance().logInfo("[LAYER]", ""); + } catch (Exception e) { + serviceMap = dirtyMap; + throw e; + } finally { + dirtyMap = null; + ServerInfo.getInstance().setReStarting(false); + } + } + + public static Map getMap() throws Exception { + if (serviceMap == null) + throw new NullPointerException("ServiceMap is NULL."); + return serviceMap; + } + + public static void initLayers() { + LogMngr.getInstance().logInfo("[JDBC]", "-----------------------------------"); + LogMngr.getInstance().logInfo("[JDBC]", "Create JDBC Layer"); + LogMngr.getInstance().logInfo("[JDBC]", "-----------------------------------"); + JdbcStoreMngr.initLayers(); + LogMngr.getInstance().logInfo("[JDBC]", ""); + LogMngr.getInstance().logInfo("[GWAVE]", "-----------------------------------"); + LogMngr.getInstance().logInfo("[GWAVE]", "Create GeoWave Layer"); + LogMngr.getInstance().logInfo("[GWAVE]", "-----------------------------------"); + GWaveStoreMngr.initLayers(); + LogMngr.getInstance().logInfo("[GWAVE]", ""); + LogMngr.getInstance().logInfo("[SHAPE]", "-----------------------------------"); + LogMngr.getInstance().logInfo("[SHAPE]", "Create Shape Layer"); + LogMngr.getInstance().logInfo("[SHAPE]", "-----------------------------------"); + ShpStoreMngr.initLayers(); + LogMngr.getInstance().logInfo("[SHAPE]", ""); + LogMngr.getInstance().logInfo("[WMTS]", "-----------------------------------"); + LogMngr.getInstance().logInfo("[WMTS]", "Create WMTS Layer"); + LogMngr.getInstance().logInfo("[WMTS]", "-----------------------------------"); + WMTSMngr.initLayers(); + LogMngr.getInstance().logInfo("[WMTS]", ""); + LogMngr.getInstance().logInfo("[TMS]", "-----------------------------------"); + LogMngr.getInstance().logInfo("[TMS]", "Create TMS Layer"); + LogMngr.getInstance().logInfo("[TMS]", "-----------------------------------"); + TMSMngr.initLayers(); + LogMngr.getInstance().logInfo("[TMS]", ""); + LogMngr.getInstance().logInfo("[IMGCACHE]", "-----------------------------------"); + LogMngr.getInstance().logInfo("[IMGCACHE]", "Create ImgCache Layer"); + LogMngr.getInstance().logInfo("[IMGCACHE]", "-----------------------------------"); + ImgCacheMngr.initLayers(); + LogMngr.getInstance().logInfo("[IMGCACHE]", ""); + LogMngr.getInstance().logInfo("[O2IMG]", "-----------------------------------"); + LogMngr.getInstance().logInfo("[O2IMG]", "Create O2Img Layer"); + LogMngr.getInstance().logInfo("[O2IMG]", "-----------------------------------"); + O2ImgLayerMngr.initLayers(); + LogMngr.getInstance().logInfo("[O2IMG]", ""); + LogMngr.getInstance().logInfo("[O2DEM]", "-----------------------------------"); + LogMngr.getInstance().logInfo("[O2DEM]", "Create O2Dem Layer"); + LogMngr.getInstance().logInfo("[O2DEM]", "-----------------------------------"); + O2DemLayerMngr.initLayers(); + LogMngr.getInstance().logInfo("[O2DEM]", ""); + LogMngr.getInstance().logInfo("[O2WPS]", "-----------------------------------"); + LogMngr.getInstance().logInfo("[O2WPS]", "Create O2WPS Layer"); + LogMngr.getInstance().logInfo("[O2WPS]", "-----------------------------------"); + WpsVecStoreMngr.initLayers(); + WpsCovStoreMngr.initLayers(); + LogMngr.getInstance().logInfo("[O2WPS]", ""); + } + + public static void reloadLayers() throws Exception { + try { + ServerInfo.getInstance().setReStarting(true); + try { + LogMngr.getInstance().logInfo("[JDBC]", "-----------------------------------"); + LogMngr.getInstance().logInfo("[JDBC]", "Relaod JDBC Layer"); + LogMngr.getInstance().logInfo("[JDBC]", "-----------------------------------"); + JdbcStoreMngr.reloadLayer(); + LogMngr.getInstance().logInfo("[JDBC]", "Success to reload JDBC Layer"); + } catch (Exception e) { + LogMngr.getInstance().logError("[JDBC]", "Fail to reload JDBC Layer :: " + e); + } finally { + LogMngr.getInstance().logInfo("[JDBC]", ""); + } + try { + LogMngr.getInstance().logInfo("[GWAVE]", "-----------------------------------"); + LogMngr.getInstance().logInfo("[GWAVE]", "Relaod GeoWave Layer"); + LogMngr.getInstance().logInfo("[GWAVE]", "-----------------------------------"); + GWaveStoreMngr.reloadLayer(); + LogMngr.getInstance().logInfo("[GWAVE]", "Success to reload GeoWave Layer"); + } catch (Exception e) { + LogMngr.getInstance().logInfo("[GWAVE]", "Fail to reload GeoWave Layer :: " + e); + } finally { + LogMngr.getInstance().logInfo("[GWAVE]", ""); + } + try { + LogMngr.getInstance().logInfo("[SHAPE]", "-----------------------------------"); + LogMngr.getInstance().logInfo("[SHAPE]", "Relaod Shape Layer"); + LogMngr.getInstance().logInfo("[SHAPE]", "-----------------------------------"); + ShpStoreMngr.reloadLayer(); + LogMngr.getInstance().logInfo("[SHAPE]", "Success to reload Shape Layer"); + } catch (Exception e) { + LogMngr.getInstance().logInfo("[SHAPE]", "Fail to reload Shape Layer :: " + e); + } finally { + LogMngr.getInstance().logInfo("[SHAPE]", ""); + } + try { + LogMngr.getInstance().logInfo("[WMTS]", "-----------------------------------"); + LogMngr.getInstance().logInfo("[WMTS]", "Relaod WMTS Layer"); + LogMngr.getInstance().logInfo("[WMTS]", "-----------------------------------"); + WMTSMngr.reloadLayer(); + } catch (Exception e) { + LogMngr.getInstance().logInfo("[WMTS]", "Fail to reload WMTS Layer :: " + e); + } finally { + LogMngr.getInstance().logInfo("[WMTS]", ""); + } + try { + LogMngr.getInstance().logInfo("[TMS]", "-----------------------------------"); + LogMngr.getInstance().logInfo("[TMS]", "Relaod TMS Layer"); + LogMngr.getInstance().logInfo("[TMS]", "-----------------------------------"); + TMSMngr.reloadLayer(); + } catch (Exception e) { + LogMngr.getInstance().logInfo("[TMS]", "Fail to reload TMS Layer :: " + e); + } finally { + LogMngr.getInstance().logInfo("[TMS]", ""); + } + try { + LogMngr.getInstance().logInfo("[IMGCACHE]", "-----------------------------------"); + LogMngr.getInstance().logInfo("[IMGCACHE]", "Relaod ImgCache Layer"); + LogMngr.getInstance().logInfo("[IMGCACHE]", "-----------------------------------"); + ImgCacheMngr.reloadLayer(); + } catch (Exception e) { + LogMngr.getInstance().logInfo("[IMGCACHE]", "Fail to reload ImgCache Layer :: " + e); + } finally { + LogMngr.getInstance().logInfo("[IMGCACHE]", ""); + } + try { + LogMngr.getInstance().logInfo("[O2IMG]", "-----------------------------------"); + LogMngr.getInstance().logInfo("[O2IMG]", "Relaod O2Img Layer"); + LogMngr.getInstance().logInfo("[O2IMG]", "-----------------------------------"); + O2ImgLayerMngr.reloadLayer(); + } catch (Exception e) { + LogMngr.getInstance().logInfo("[O2IMG]", "Fail to reload O2Img Layer :: " + e); + } finally { + LogMngr.getInstance().logInfo("[O2IMG]", ""); + } + try { + LogMngr.getInstance().logInfo("[O2DEM]", "-----------------------------------"); + LogMngr.getInstance().logInfo("[O2DEM]", "Relaod O2Dem Layer"); + LogMngr.getInstance().logInfo("[O2DEM]", "-----------------------------------"); + O2DemLayerMngr.reloadLayer(); + } catch (Exception e) { + LogMngr.getInstance().logInfo("[O2DEM]", "Fail to reload O2Dem Layer :: " + e); + } finally { + LogMngr.getInstance().logInfo("[O2DEM]", ""); + } + try { + LogMngr.getInstance().logInfo("[O2WPS]", "-----------------------------------"); + LogMngr.getInstance().logInfo("[O2WPS]", "Relaod O2WPS Layer"); + LogMngr.getInstance().logInfo("[O2WPS]", "-----------------------------------"); + WpsVecStoreMngr.reloadLayer(); + WpsCovStoreMngr.reloadLayer(); + LogMngr.getInstance().logInfo("[O2WPS]", "Success to reload O2WPS Layer"); + } catch (Exception e) { + LogMngr.getInstance().logInfo("[O2WPS]", "Fail to reload O2WPS Layer :: " + e); + } finally { + LogMngr.getInstance().logInfo("[O2WPS]", ""); + } + } catch (Exception e) { + throw e; + } finally { + ServerInfo.getInstance().setReStarting(false); + LogMngr.getInstance().logInfo("[LAYER]", ""); + } + } + + public static void reloadStyle(String layerName) throws Exception { + try { + ServerInfo.getInstance().setReStarting(true); + if (layerName != null) + layerName = layerName.trim().toUpperCase(); + ArrayList layers = getMap().getAllLayers(); + for (Layer layer : layers) { + if (layerName != null && + !layerName.equalsIgnoreCase(layer.getName())) + continue; + try { + if (layer instanceof FeatureLayer) { + ((FeatureLayer)layer).reloadServiceStyle(); + } else if (layer instanceof O2DemLayer) { + ((O2DemLayer)layer).reloadServiceStyle(); + } + LogMngr.getInstance().logInfo("[STYLE]", "Success to reload Style for this layer [" + layer.getName() + "]"); + } catch (Exception e) { + LogMngr.getInstance().logInfo("[STYLE]", "Fail to reload Style for this layer [" + layer.getName() + "] :: " + e); + continue; + } finally { + LogMngr.getInstance().logInfo("[STYLE]", ""); + } + } + } catch (Exception e) { + throw e; + } finally { + ServerInfo.getInstance().setReStarting(false); + LogMngr.getInstance().logInfo("[STYLE]", ""); + } + } + + private static File getWebInfFolder() throws Exception { + URL url = ServerContext.class.getResource("/"); + return (new File(url.toURI())).getParentFile(); + } + + public static File getConfFolder() throws Exception { + if (confFolder == null) + try { + confFolder = new File(getWebInfFolder(), CONF_FOLDER_NAME); + if (!confFolder.exists()) + confFolder.mkdir(); + confFolder.setReadable(true, false); + confFolder.setWritable(true, false); + } catch (SecurityException e) { + throw new SecurityException("Folder [WEB-INF" + CONF_FOLDER_NAME + "] is not accessible.", e); + } catch (Exception e) { + confFolder = null; + throw new Exception("Folder [WEB-INF" + CONF_FOLDER_NAME + "] has problem.", e); + } + return confFolder; + } + + public static File setConfFolder(File path) throws Exception { + if (path == null || + !path.exists() || + path.isFile()) + throw new IOException("Conf Folder is not exist."); + confFolder = path; + return path; + } + + public static File getStylesFolder() throws Exception { + if (stylesFolder == null) + try { + stylesFolder = new File(getWebInfFolder(), STYLES_FOLDER_NAME); + if (!stylesFolder.exists()) + stylesFolder.mkdir(); + stylesFolder.setReadable(true, false); + stylesFolder.setWritable(true, false); + } catch (SecurityException e) { + LogMngr.getInstance().logError("[CONFIG]", "Folder [WEB-INF" + STYLES_FOLDER_NAME + "] is not accessible."); + throw e; + } catch (Exception e) { + stylesFolder = null; + LogMngr.getInstance().logError("[CONFIG]", "Folder [WEB-INF" + STYLES_FOLDER_NAME + "] has problem."); + throw e; + } + return stylesFolder; + } + + public static File setStylesFolder(File path) throws Exception { + if (path == null || + !path.exists() || + path.isFile()) + throw new IOException("Styles Folder is not exist."); + stylesFolder = path; + return path; + } + + public static File getPluginsFolder() throws Exception { + if (pluginsFolder == null) + try { + pluginsFolder = new File(getWebInfFolder(), PLUGINS_FOLDER_NAME); + if (!pluginsFolder.exists()) + pluginsFolder.mkdir(); + pluginsFolder.setReadable(true, false); + pluginsFolder.setWritable(true, false); + } catch (SecurityException e) { + LogMngr.getInstance().logError("[CONFIG]", "Folder [WEB-INF" + PLUGINS_FOLDER_NAME + "] is not accessible."); + throw e; + } catch (Exception e) { + pluginsFolder = null; + LogMngr.getInstance().logError("[CONFIG]", "Folder [WEB-INF" + PLUGINS_FOLDER_NAME + "] has problem."); + throw e; + } + return pluginsFolder; + } + + public static File setPluginsFolder(File path) throws Exception { + if (path == null || + !path.exists() || + path.isFile()) + throw new IOException("Plugins Folder is not exist."); + pluginsFolder = path; + return path; + } + + public static void initOptions() { + docIndent = null; + useNSPrefix = null; + defaultMaxFeatures = null; + } + + public static Integer getDocIndent() { + if (docIndent == null) { + String indent = (String)ServerConfiguration.getInstance().getConfMap().get("conf.xml.map.docindent"); + if (ServerUtil.isNullString(indent)) { + docIndent = Integer.valueOf(2); + } else { + try { + double value = Double.parseDouble(indent); + docIndent = Integer.valueOf((int)value); + if (docIndent.intValue() < 0) + docIndent = Integer.valueOf(0); + } catch (Exception e) { + docIndent = Integer.valueOf(2); + } + } + } + return docIndent; + } + + public static boolean isUseNSPrefix() { + if (useNSPrefix == null) { + String useNS = (String)ServerConfiguration.getInstance().getConfMap().get("conf.xml.map.usedefaultnsprefix"); + if (ServerUtil.isNullString(useNS)) { + useNSPrefix = Boolean.valueOf(true); + } else { + useNSPrefix = Boolean.valueOf(ServerUtil.getBooleanValue(useNS)); + } + } + return useNSPrefix.booleanValue(); + } + + public static Integer getDefaultMaxFeatrues() { + if (defaultMaxFeatures == null) { + String defaultValue = (String)ServerConfiguration.getInstance().getConfMap().get("conf.xml.map.default.max.features"); + if (ServerUtil.isNullString(defaultValue)) { + defaultMaxFeatures = Integer.valueOf(10000); + } else { + try { + defaultMaxFeatures = Integer.valueOf(defaultValue.trim()); + if (defaultMaxFeatures.intValue() <= 0) + defaultMaxFeatures = Integer.valueOf(2147483647); + } catch (Exception e) { + defaultMaxFeatures = Integer.valueOf(10000); + } + } + } + return defaultMaxFeatures; + } + + public static boolean isEncryption() { + if (encryption == null) { + String useEncryption = (String)ServerConfiguration.getInstance().getConfMap().get("conf.xml.map.encryption"); + if (ServerUtil.isNullString(useEncryption)) { + encryption = Boolean.valueOf(false); + } else { + encryption = Boolean.valueOf(ServerUtil.getBooleanValue(useEncryption)); + } + } + return encryption.booleanValue(); + } +} \ No newline at end of file diff --git a/src/main/java/com/geotwo/webserver/core/ServerInfo.java b/src/main/java/com/geotwo/webserver/core/ServerInfo.java new file mode 100644 index 0000000..964ce07 --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/ServerInfo.java @@ -0,0 +1,34 @@ +package com.geotwo.webserver.core; + +public class ServerInfo +{ + private static ServerInfo instance = null; + + private boolean isStarted = false; + private boolean isReStarting = false; + + public static ServerInfo getInstance() + { + if (instance == null) { + instance = new ServerInfo(); + } + return instance; + } + + public boolean isStarted() + { + return this.isStarted; + } + + public void setStarted(boolean isStarted) { + this.isStarted = isStarted; + } + + public boolean isReStarting() { + return this.isReStarting; + } + + public void setReStarting(boolean isReStarting) { + this.isReStarting = isReStarting; + } +} diff --git a/src/main/java/com/geotwo/webserver/core/cache/ImgCacheMngr.java b/src/main/java/com/geotwo/webserver/core/cache/ImgCacheMngr.java new file mode 100644 index 0000000..905fa88 --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/cache/ImgCacheMngr.java @@ -0,0 +1,278 @@ +package com.geotwo.webserver.core.cache; + +import com.geotwo.webserver.core.ServerContext; +import com.geotwo.webserver.core.cache.ic.CacheFormat; +import com.geotwo.webserver.core.cache.ic.CacheLevel; +import com.geotwo.webserver.core.cache.ic.CacheLevelSet; +import com.geotwo.webserver.core.cache.ic.ImgCacheLayer; +import com.geotwo.webserver.core.log.LogMngr; +import com.geotwo.webserver.core.util.AVList; +import com.geotwo.webserver.core.util.ServerUtil; +import com.geotwo.webserver.core.vector.crs.CRSMngr; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.concurrent.ConcurrentHashMap; +import javax.management.modelmbean.XMLParseException; +import org.geotools.geometry.jts.ReferencedEnvelope; +import org.jdom.Attribute; +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.input.SAXBuilder; +import org.opengis.referencing.crs.CoordinateReferenceSystem; + +public class ImgCacheMngr { + private static ConcurrentHashMap cacheLayerStore = new ConcurrentHashMap(); + + private static ConcurrentHashMap dirtyCacheLayerStore; + + public static void initLayers() { + cacheLayerStore = new ConcurrentHashMap(); + synchronized (cacheLayerStore) { + try { + File confFile = new File( + ServerContext.getPluginsFolder(), + String.valueOf(ServerContext.getMap().getName()) + ".IMGCACHE"); + if (!confFile.exists()) + throw new IOException("Configuration file is not exist :: " + confFile.getAbsolutePath()); + LogMngr.getInstance().logDebug("[IMGCACHE]", + "Now create [" + ServerContext.getMap().getName() + "] ImgCache Layer"); + AVList params = parseImgCacheLayer(confFile); + File cacheDir = (File)params.getValue("img.cache.conf.cache.location"); + CacheFormat cacheFormat = (CacheFormat)params.getValue("img.cache.conf.cache.format"); + CacheLevelSet cacheLevelSet = (CacheLevelSet)params.getValue("img.cache.conf.cache.levelset"); + ArrayList layers = + (ArrayList)params.getValue("img.cache.conf.layers"); + for (ImgCacheLayer layer : layers) { + try { + layer.setCacheDir(cacheDir); + layer.setCacheFormat(cacheFormat); + layer.setCacheLevelSet(cacheLevelSet.copy()); + cacheLayerStore.put(layer.getLayerName(), layer); + LogMngr.getInstance().logInfo("[IMGCACHE]", + "[" + layer.getLayerName() + "] Add ImgCache Layer Success"); + LogMngr.getInstance().logInfo("[IMGCACHE]", ""); + } catch (Exception e) { + LogMngr.getInstance().logError("[IMGCACHE]", + "[" + layer.getLayerName() + "] Add ImgCache Layer Fail :: " + e.getMessage()); + } + } + if (cacheLayerStore.size() == 0) { + LogMngr.getInstance().logError("[IMGCACHE]", + "Create ImgCache Layer Fail :: Layer Count is [0]"); + } else { + LogMngr.getInstance().logInfo("[IMGCACHE]", + "Create ImgCache Layer Success :: Layer Count is [" + cacheLayerStore.size() + "]"); + } + } catch (Exception e) { + LogMngr.getInstance().logError("[IMGCACHE]", + "Create ImgCache Layer Fail :: " + e.getMessage()); + } + } + } + + private static AVList parseImgCacheLayer(File xml) throws Exception { + LogMngr.getInstance().logDebug("[IMGCACHE]", + "[" + xml.getName() + "] Parse ImgCache Layer"); + SAXBuilder builder = new SAXBuilder(); + Document doc = builder.build(xml); + Element root = doc.getRootElement(); + if (!root.getName().equalsIgnoreCase("IMAGE_CACHE")) + throw new XMLParseException(String.valueOf(xml.getName()) + " > Has no tag "); + AVList params = new AVList(); + for (Object child : root.getChildren()) { + if (child instanceof Element) { + Element element = (Element)child; + if (element.getName().equalsIgnoreCase("LAYERS")) { + params.setValue("img.cache.conf.layers", parseLayers(element)); + continue; + } + if (element.getName().equalsIgnoreCase("CACHELOCATION")) { + params.setValue("img.cache.conf.cache.location", parseLoc(element)); + continue; + } + if (element.getName().equalsIgnoreCase("CACHEFORMAT")) { + CacheFormat cFormat = new CacheFormat(); + for (Object attr : element.getAttributes()) { + if (attr instanceof Attribute) { + Attribute tileformatAttr = (Attribute)attr; + if (tileformatAttr.getName().equalsIgnoreCase("WIDTH")) { + cFormat.setWidth(Integer.parseInt(tileformatAttr.getValue().trim())); + continue; + } + if (tileformatAttr.getName().equalsIgnoreCase("HEIGHT")) { + cFormat.setHeight(Integer.parseInt(tileformatAttr.getValue().trim())); + continue; + } + if (tileformatAttr.getName().equalsIgnoreCase("FORMAT")) + cFormat.setFormat(tileformatAttr.getValue().trim()); + } + } + params.setValue("img.cache.conf.cache.format", cFormat); + continue; + } + if (element.getName().equalsIgnoreCase("LEVELSET")) { + CacheLevelSet lvlSet = new CacheLevelSet(); + for (Object level : element.getChildren()) { + if (level instanceof Element) { + Element levelElement = (Element)level; + if (levelElement.getName().equalsIgnoreCase("LEVEL")) + lvlSet.addLevel(parseLevel(levelElement)); + } + } + params.setValue("img.cache.conf.cache.levelset", lvlSet); + } + } + } + return params; + } + + private static CacheLevel parseLevel(Element ele) throws Exception { + Integer level = null; + Double resoltution = null; + Double scale = null; + for (Object attr : ele.getAttributes()) { + if (attr instanceof Attribute) { + Attribute matrixAttr = (Attribute)attr; + if (matrixAttr.getName().equalsIgnoreCase("LEVEL")) { + level = Integer.valueOf(Integer.parseInt(matrixAttr.getValue().trim())); + continue; + } + if (matrixAttr.getName().equalsIgnoreCase("RESOLUTION")) { + resoltution = Double.valueOf(Double.parseDouble(matrixAttr.getValue().trim())); + continue; + } + if (matrixAttr.getName().equalsIgnoreCase("SCALE")) + scale = Double.valueOf(Double.parseDouble(matrixAttr.getValue().trim())); + } + } + if (level == null) + throw new XMLParseException(" Attribute value [LAVEL] is null."); + if (resoltution == null && scale == null) + throw new XMLParseException(" Attribute value [RESOLUTION,SCALE] is null."); + return new CacheLevel(level, resoltution, scale); + } + + private static ReferencedEnvelope parseExtent(Element bbox) throws Exception { + String crsName = null; + for (Object attr : bbox.getAttributes()) { + if (attr instanceof Attribute) { + Attribute bboxAttr = (Attribute)attr; + if (bboxAttr.getName().equalsIgnoreCase("CRS")) + crsName = bboxAttr.getValue().trim().toUpperCase(); + } + } + CoordinateReferenceSystem crs = CRSMngr.getCRS(crsName); + if (crs == null) + throw new XMLParseException("<" + bbox.getName() + "> Attribute value [CRS] is Not Available. :: [" + crsName + "] is not Exists."); + double minX = 0.0D; + double minY = 0.0D; + double maxX = 0.0D; + double maxY = 0.0D; + for (Object subChild : bbox.getChildren()) { + if (subChild instanceof Element) { + Element subElement = (Element)subChild; + if (subElement.getName().equalsIgnoreCase("LOWERCORNER")) { + String[] coord = subElement.getTextTrim().split(","); + if (coord.length != 2) + coord = subElement.getTextTrim().split("\\s+"); + if (coord.length != 2) + throw new XMLParseException(" value is Not Coordinate. :: " + subElement.getText()); + minX = Double.parseDouble(coord[0]); + minY = Double.parseDouble(coord[1]); + continue; + } + if (subElement.getName().equalsIgnoreCase("UPPERCORNER")) { + String[] coord = subElement.getTextTrim().split(","); + if (coord.length != 2) + coord = subElement.getTextTrim().split("\\s+"); + if (coord.length != 2) + throw new XMLParseException(" value is Not Coordinate. :: " + subElement.getText()); + maxX = Double.parseDouble(coord[0]); + maxY = Double.parseDouble(coord[1]); + } + } + } + return new ReferencedEnvelope(minX, maxX, minY, maxY, crs); + } + + private static File parseLoc(Element ele) throws IOException { + File dir = new File(ele.getTextTrim()); + if (dir.exists()) { + for (Object attr : ele.getAttributes()) { + if (attr instanceof Attribute) { + Attribute layerAttr = (Attribute)attr; + if (layerAttr.getName().equalsIgnoreCase("CLEARBEFORE")) + if (ServerUtil.getBooleanValue(layerAttr.getValue())) + ServerUtil.removeFile(dir, true); + } + } + } else if (!dir.mkdirs()) { + throw new IOException("Can't access CacheLocation [" + dir.getAbsolutePath() + "]"); + } + return dir; + } + + private static ArrayList parseLayers(Element ele) throws IOException { + ArrayList layers = new ArrayList(); + for (Object child : ele.getChildren()) { + if (child instanceof Element) { + Element layer = (Element)child; + if (layer.getName().equalsIgnoreCase("LAYER")) { + String name = null; + String style = "DEFAULT"; + for (Object attr : layer.getAttributes()) { + if (attr instanceof Attribute) { + Attribute layerAttr = (Attribute)attr; + if (layerAttr.getName().equalsIgnoreCase("NAME")) { + name = layerAttr.getValue().trim(); + continue; + } + if (layerAttr.getName().equalsIgnoreCase("STYLE")) + style = layerAttr.getValue().trim(); + } + } + try { + layers.add(new ImgCacheLayer(name, style)); + } catch (Exception e) { + LogMngr.getInstance().logError("[IMGCACHE]", + "Layer name [" + name + "] has problem :: " + e); + } + } + } + } + if (layers.size() == 0) + throw new IOException("LAYER count is zero."); + return layers; + } + + public static synchronized void reloadLayer() throws Exception { + try { + dirtyCacheLayerStore = cacheLayerStore; + initLayers(); + dirtyCacheLayerStore.clear(); + dirtyCacheLayerStore = null; + LogMngr.getInstance().logInfo("[IMGCACHE]", "Success to reload ImgCache Layer."); + } catch (Exception e) { + LogMngr.getInstance().logError("[IMGCACHE]", "Fail to reload ImgCache Layer. Now use previous ImgCache Layer :: " + e); + cacheLayerStore = dirtyCacheLayerStore; + throw e; + } + } + + public static ImgCacheLayer getImgCacheLayer(String id) throws Exception { + if (ServerUtil.isNullString(id)) + throw new NullPointerException("ID value is NULL."); + ImgCacheLayer layer = cacheLayerStore.get(id.trim().toUpperCase()); + if (layer == null) + throw new NullPointerException("Layer [" + id.trim() + "] is not exist in ImageCache Service."); + return layer; + } + + public static void removeImgCache(String id) throws Exception { + synchronized (cacheLayerStore) { + ImgCacheLayer layer = getImgCacheLayer(id); + ServerUtil.removeFile(layer.getCacheDir(), true); + } + } +} diff --git a/src/main/java/com/geotwo/webserver/core/cache/LogCacheManager.java b/src/main/java/com/geotwo/webserver/core/cache/LogCacheManager.java new file mode 100644 index 0000000..d6b753f --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/cache/LogCacheManager.java @@ -0,0 +1,179 @@ +package com.geotwo.webserver.core.cache; + +import com.geotwo.webserver.core.cache.util.FileComparator; +import com.geotwo.webserver.core.log.LogMngr; +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Timer; +import java.util.TimerTask; + +public class LogCacheManager { + private static LogCacheManager instance; + + private Timer timer; + + private long timerRepeat; + + private long cachePeriod; + + private long folderSize; + + private File logDir = null; + + private String type = null; + + private int value = 0; + + private LogCacheManager() { + this.timerRepeat = 60000L; + this.timer = new Timer(); + } + + public static LogCacheManager getInstance() { + if (instance == null) + instance = new LogCacheManager(); + return instance; + } + + public void start(HashMap map) { + String dirValue = (String)map.get("conf.xml.log.dir"); + this.logDir = new File(dirValue.trim()); + if (!this.logDir.exists()) { + LogMngr.getInstance().logError("[CACHE]", "Log Cache Directory is not exist. Now log cache always saved."); + return; + } + if (this.logDir.isFile()) { + LogMngr.getInstance().logError("[CACHE]", "Log Cache Directory is not Directory. Now log cache always saved."); + return; + } + this.type = (String)map.get("conf.xml.log.cache.type"); + if (this.type == null || this.type.trim().equals("")) { + LogMngr.getInstance().logError("[CACHE]", "Log Cache Type is NULL. Now log cache always saved."); + return; + } + if (!this.type.trim().equalsIgnoreCase("SIZE") && !this.type.trim().equalsIgnoreCase("DAY")) { + LogMngr.getInstance().logError("[CACHE]", "Log Cache Type is support only SIZE/DAY. Now log cache always saved."); + return; + } + this.type = this.type.trim().toUpperCase(); + String sValue = (String)map.get("conf.xml.log.cache.value"); + try { + if (sValue == null || sValue.trim().equals("")) { + LogMngr.getInstance().logError("[CACHE]", "Log Cache Value is NULL. Now log cache always saved."); + return; + } + this.value = Integer.parseInt(sValue); + } catch (Exception e) { + LogMngr.getInstance().logError("[CACHE]", "Log Cache Value is only support Integer[" + sValue + "]. Now log cache always saved."); + return; + } + if (this.value < 1) { + LogMngr.getInstance().logError("[CACHE]", "Now log cache always saved. :: Log cache value is " + this.value); + return; + } + if (this.type.trim().equalsIgnoreCase("SIZE")) { + this.folderSize = this.value; + LogMngr.getInstance().logInfo("[CACHE]", "Log cache managed by Directory Volume. :: " + this.value + "/MB"); + } else if (this.type.trim().equalsIgnoreCase("DAY")) { + this.cachePeriod = this.value; + LogMngr.getInstance().logInfo("[CACHE]", "Log cache managed by creation period of File. :: " + this.value + "/Day"); + } + this.timerRepeat = 21600000L; + this.timer.cancel(); + this.timer = new Timer(); + this.timer.scheduleAtFixedRate(new CacheTimerTask(), 600000L, this.timerRepeat); + LogMngr.getInstance().logInfo("[CACHE]", ""); + } + + public void stop() { + this.timer.cancel(); + this.timer.purge(); + } + + class CacheTimerTask extends TimerTask { + public void run() { + LogMngr.getInstance().logDebug("[CACHE]", "------------------------------"); + LogMngr.getInstance().logDebug("[CACHE]", "Run log cache management"); + LogMngr.getInstance().logDebug("[CACHE]", "------------------------------"); + if (LogCacheManager.this.type.equalsIgnoreCase("SIZE")) { + LogMngr.getInstance().logDebug("[CACHE]", "Check Directory volume. Every " + (LogCacheManager.this.timerRepeat / 1000L / 60L) + "/min, Limits " + LogCacheManager.this.folderSize + "MB"); + ArrayList fileList = new ArrayList(); + readFile(fileList, LogCacheManager.this.logDir); + double cacheSize = getFileSize(fileList); + double size = (LogCacheManager.this.folderSize * 1024L * 1024L); + if (size < cacheSize) { + Collections.sort(fileList, (Comparator)new FileComparator()); + for (int i = 0; i < fileList.size() && + fileList.size() > 4; i++) { + File dFile = fileList.get(i); + if (dFile.exists() && dFile.isFile()) { + cacheSize -= ((File)fileList.get(i)).length(); + dFile.delete(); + LogMngr.getInstance().logDebug("[CACHE]", "Remove log cache by Size. [" + dFile + "]"); + fileList.remove(i); + i--; + if (dFile.getParentFile().isDirectory() && (dFile.getParentFile().list()).length == 0) { + File pFile = dFile.getParentFile(); + dFile = null; + pFile.delete(); + } + } + if (size > cacheSize) + break; + } + } + } else if (LogCacheManager.this.type.equalsIgnoreCase("DAY")) { + LogMngr.getInstance().logDebug("[CACHE]", "Check creation time of File. Every " + (LogCacheManager.this.timerRepeat / 1000L / 60L) + "/min, Limits " + LogCacheManager.this.cachePeriod + "Days"); + ArrayList fileList = new ArrayList(); + readFile(fileList, LogCacheManager.this.logDir); + Collections.sort(fileList, (Comparator)new FileComparator()); + long time = 86400000L * LogCacheManager.this.cachePeriod; + for (int i = 0; i < fileList.size(); ) { + if (fileList.size() <= 4) + break; + File dFile = fileList.get(i); + if (time < System.currentTimeMillis() - dFile.lastModified()) { + if (dFile.exists() && dFile.isFile()) { + dFile.delete(); + LogMngr.getInstance().logDebug("[CACHE]", "Remove log cache by Day. [" + dFile + "]"); + fileList.remove(i); + i--; + if (dFile.getParentFile().isDirectory() && (dFile.getParentFile().list()).length == 0) { + File pFile = dFile.getParentFile(); + dFile = null; + pFile.delete(); + } + } + i++; + } + break; + } + } + } + + private void readFile(ArrayList list, File file) { + if (file.exists()) + if (file.isDirectory()) { + File[] files = file.listFiles(); + if (files == null || files.length == 0) { + file.delete(); + } else { + for (int i = 0; i < files.length; i++) + readFile(list, files[i]); + } + } else { + list.add(file); + } + } + + private double getFileSize(ArrayList list) { + double size = 0.0D; + for (File file : list) + size += file.length(); + return size; + } + } +} diff --git a/src/main/java/com/geotwo/webserver/core/cache/ic/CacheFormat.java b/src/main/java/com/geotwo/webserver/core/cache/ic/CacheFormat.java new file mode 100644 index 0000000..833b49a --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/cache/ic/CacheFormat.java @@ -0,0 +1,31 @@ +package com.geotwo.webserver.core.cache.ic; + +public class CacheFormat { + int width = 256; + int height = 256; + String format = "png"; + + public int getWidth() { + return this.width; + } + + public int getHeight() { + return this.height; + } + + public String getFormat() { + return this.format; + } + + public void setWidth(int width) { + this.width = width; + } + + public void setHeight(int height) { + this.height = height; + } + + public void setFormat(String format) { + this.format = format; + } +} \ No newline at end of file diff --git a/src/main/java/com/geotwo/webserver/core/cache/ic/CacheLevel.java b/src/main/java/com/geotwo/webserver/core/cache/ic/CacheLevel.java new file mode 100644 index 0000000..27ade9d --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/cache/ic/CacheLevel.java @@ -0,0 +1,70 @@ +package com.geotwo.webserver.core.cache.ic; + +import java.io.File; +import javax.management.modelmbean.XMLParseException; +import org.geotools.geometry.jts.ReferencedEnvelope; + +public class CacheLevel { + private CacheLevelSet levelSet; + private final int level; + private Double resolution; + private Double scaleDenominator; + + public CacheLevel(Integer lv, Double res, Double scale) throws Exception { + this.level = lv; + this.resolution = res; + this.scaleDenominator = scale; + if (this.resolution == null && this.scaleDenominator == null) { + throw new XMLParseException(" Attribute value [RESOLUTION or SCALE] is null. LEVEL [" + this.level + "]"); + } + } + + public int getLevel() { + return this.level; + } + + public Double getResolution() { + return this.resolution; + } + + public Double getScale() { + return this.scaleDenominator; + } + + public ReferencedEnvelope getBBox() { + return this.levelSet.getBBox(); + } + + public int getCacheSizeW() { + return this.levelSet.getCacheSizeW(); + } + + public int getCacheSizeH() { + return this.levelSet.getCacheSizeH(); + } + + public File getCachePath() { + return new File(this.levelSet.getCacheDir(), "/" + this.level); + } + + public String getCacheFormat() { + return this.levelSet.getCacheFormat(); + } + + public String getLayerName() { + return this.levelSet.getLayerName(); + } + + public String getLayerStyle() { + return this.levelSet.getLayerStyle(); + } + + public void refineCacheLevel(CacheLevelSet lSet) throws Exception { + this.levelSet = lSet; + if (this.resolution == null) { + this.resolution = lSet.calResolution(this.scaleDenominator); + } else if (this.scaleDenominator == null) { + this.scaleDenominator = lSet.calScaleDenominator(this.resolution); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/geotwo/webserver/core/cache/ic/CacheLevelSet.java b/src/main/java/com/geotwo/webserver/core/cache/ic/CacheLevelSet.java new file mode 100644 index 0000000..b876d6e --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/cache/ic/CacheLevelSet.java @@ -0,0 +1,94 @@ +package com.geotwo.webserver.core.cache.ic; + +import java.io.File; +import java.util.TreeMap; +import org.geotools.geometry.jts.ReferencedEnvelope; +import org.opengis.referencing.crs.GeographicCRS; + +public class CacheLevelSet { + private final double dpi = 90.7142857142857; + private final double OGC_DEGREE_TO_METER = 111319.49079327358; + private final double OGC_INCH_TO_METER = 0.0254; + private final boolean isTopLeft = false; + private ImgCacheLayer cacheLayer; + private TreeMap levelSet = new TreeMap(); + + public CacheLevelSet copy() throws Exception { + CacheLevelSet copy = new CacheLevelSet(); + for (CacheLevel lvl : this.levelSet.values()) { + CacheLevel level = new CacheLevel(Integer.valueOf(lvl.getLevel()), lvl.getResolution(), lvl.getScale()); + copy.addLevel(level); + } + return copy; + } + + public void addLevel(CacheLevel lvl) { + this.levelSet.put(lvl.getLevel(), lvl); + } + + public CacheLevel getLevel(double res) { + CacheLevel level = null; + for (CacheLevel lvl : this.levelSet.values()) { + if (level == null) { + level = lvl; + continue; + } + if (!(Math.abs(level.getResolution() - res) > Math.abs(lvl.getResolution() - res))) continue; + level = lvl; + } + return level; + } + + public ReferencedEnvelope getBBox() { + return this.cacheLayer.getBBox(); + } + + public int getCacheSizeW() { + return this.cacheLayer.getCacheSizeW(); + } + + public int getCacheSizeH() { + return this.cacheLayer.getCacheSizeH(); + } + + public File getCacheDir() { + return this.cacheLayer.getCacheDir(); + } + + public String getCacheFormat() { + return this.cacheLayer.getCacheFormat(); + } + + public String getLayerName() { + return this.cacheLayer.getLayerName(); + } + + public String getLayerStyle() { + return this.cacheLayer.getLayerStyle(); + } + + public boolean isTopLeft() { + return false; + } + + public double calScaleDenominator(double res) { + if (this.cacheLayer.getBBox().getCoordinateReferenceSystem() instanceof GeographicCRS) { + return res * 111319.49079327358 / 2.8000000000000003E-4; + } + return res / 2.8000000000000003E-4; + } + + public double calResolution(double scale) { + if (this.cacheLayer.getBBox().getCoordinateReferenceSystem() instanceof GeographicCRS) { + return scale * 2.8000000000000003E-4 * 8.983152841195214E-6; + } + return scale * 2.8000000000000003E-4; + } + + public void refindCacheLevelSet(ImgCacheLayer clayer) throws Exception { + this.cacheLayer = clayer; + for (CacheLevel level : this.levelSet.values()) { + level.refineCacheLevel(this); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/geotwo/webserver/core/cache/ic/ImgCacheLayer.java b/src/main/java/com/geotwo/webserver/core/cache/ic/ImgCacheLayer.java new file mode 100644 index 0000000..954ff9e --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/cache/ic/ImgCacheLayer.java @@ -0,0 +1,80 @@ +package com.geotwo.webserver.core.cache.ic; + +import com.geotwo.webserver.core.ServerContext; +import com.geotwo.webserver.core.map.layer.Layer; +import com.geotwo.webserver.core.util.ServerUtil; +import java.io.File; +import java.io.IOException; +import org.geotools.geometry.jts.ReferencedEnvelope; +import org.opengis.referencing.crs.CoordinateReferenceSystem; + +public class ImgCacheLayer { + private Layer layer; + + private String layerStyle = "DEFAULT"; + + private File cacheDir; + + private CacheFormat cacheFormat = new CacheFormat(); + + private CacheLevelSet levelSet; + + public ImgCacheLayer(String name, String style) throws Exception { + this.layer = ServerContext.getMap().getLayer(name); + if (!ServerUtil.isNullString(style)) + this.layerStyle = style; + } + + public String getLayerName() { + return this.layer.getName(); + } + + public String getLayerStyle() { + return this.layerStyle; + } + + public ReferencedEnvelope getBBox() { + return this.layer.getBBox(); + } + + public CoordinateReferenceSystem getCRS() { + return this.layer.getCRS(); + } + + public File getCacheDir() { + return this.cacheDir; + } + + public void setCacheFormat(CacheFormat format) { + if (format != null) + this.cacheFormat = format; + } + + public int getCacheSizeW() { + return this.cacheFormat.getWidth(); + } + + public int getCacheSizeH() { + return this.cacheFormat.getHeight(); + } + + public String getCacheFormat() { + return this.cacheFormat.getFormat(); + } + + public CacheLevelSet getCacheLevelSet() { + return this.levelSet; + } + + public void setCacheDir(File dir) throws IOException { + this.cacheDir = new File(dir, this.layer.getName()); + if (!this.cacheDir.exists() && + !this.cacheDir.mkdirs()) + throw new IOException("Can't access CacheLocation for this layer [" + this.cacheDir.getAbsolutePath() + "]"); + } + + public void setCacheLevelSet(CacheLevelSet lSet) throws Exception { + this.levelSet = lSet; + this.levelSet.refindCacheLevelSet(this); + } +} diff --git a/src/main/java/com/geotwo/webserver/core/cache/util/FileComparator.java b/src/main/java/com/geotwo/webserver/core/cache/util/FileComparator.java new file mode 100644 index 0000000..d195cc9 --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/cache/util/FileComparator.java @@ -0,0 +1,16 @@ +package com.geotwo.webserver.core.cache.util; + +import java.io.File; +import java.util.Comparator; + +public class FileComparator + implements Comparator +{ + public int compare(File f1, File f2) + { + if (f1.lastModified() > f2.lastModified()) { + return 1; + } + return -1; + } +} diff --git a/src/main/java/com/geotwo/webserver/core/coverage/O2DemLayerMngr.java b/src/main/java/com/geotwo/webserver/core/coverage/O2DemLayerMngr.java new file mode 100644 index 0000000..0488c8b --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/coverage/O2DemLayerMngr.java @@ -0,0 +1,188 @@ +package com.geotwo.webserver.core.coverage; + +import com.geotwo.webserver.core.ServerContext; +import com.geotwo.webserver.core.coverage.o2layer.O2LayerInfo; +import com.geotwo.webserver.core.coverage.o2layer.O2LayerLevelSet; +import com.geotwo.webserver.core.coverage.o2layer.O2LayerUtil; +import com.geotwo.webserver.core.log.LogMngr; +import com.geotwo.webserver.core.map.LayerFactory; +import com.geotwo.webserver.core.map.layer.Layer; +import com.geotwo.webserver.core.map.layer.O2DemLayer; +import com.geotwo.webserver.core.util.AVList; +import com.geotwo.webserver.core.util.ServerUtil; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import org.opengis.referencing.crs.CoordinateReferenceSystem; + +public class O2DemLayerMngr { + public static void initLayers() { + try { + File dir = ServerContext.getPluginsFolder(); + String fileName = String.valueOf(ServerContext.getMap().getName()) + LayerFactory.LayerType.O2DEM.getPrefix(); + File confFile = ServerUtil.findFile(dir, fileName); + if (confFile == null) { + LogMngr.getInstance().logError("[O2DEM]", + "Skip create O2DemLayer :: Layer Configuration File [" + confFile + "] is not exist"); + return; + } + LogMngr.getInstance().logDebug("[O2DEM]", + "[" + confFile.getName() + "] Now create O2DemLayer from this configuration"); + ArrayList layerInfoList = parseO2DemLayer(confFile); + if (layerInfoList == null || layerInfoList.isEmpty()) { + LogMngr.getInstance().logError("[O2DEM]", + "[" + confFile.getName() + "] Fail to create O2DemLayer :: O2DemLayer size is ZERO[0] from this configuration"); + return; + } + for (O2LayerInfo info : layerInfoList) { + LogMngr.getInstance().logDebug("[O2DEM]", + "[" + confFile.getName() + "][" + info.getLayerName() + "] Now create this O2DemLayer"); + try { + addLayer(info.getLayerPath(), info.getLayerName(), info.getLayerCRS(), info.getDesc(), + info.getMinData(), info.getMaxData(), info.getNoData()); + LogMngr.getInstance().logInfo("[O2DEM]", + "[" + confFile.getName() + "][" + info.getLayerName() + "] Add Layer Success :: " + + "[Map:" + ServerContext.getMap().getName() + "/Layer:" + info.getLayerName() + "] : " + + "[RefServer:" + LayerFactory.LayerType.O2IMG.getType() + "/RefSource:" + info.getLayerPath() + "]"); + } catch (Exception e) { + LogMngr.getInstance().logError("[O2DEM]", + "[" + confFile.getName() + "][" + info.getLayerName() + "] Add Layer Fail :: " + e); + } + LogMngr.getInstance().logDebug("[O2DEM]", ""); + } + } catch (Exception e) { + LogMngr.getInstance().logError("[O2DEM]", "Create O2DemLayer Fail :: " + e); + } + } + + private static ArrayList parseO2DemLayer(File conf) { + if (!conf.exists()) { + LogMngr.getInstance().logError("[O2DEM]", + "[" + conf.getName() + "] Create O2DemLayer Fail :: O2DemLayer configuration is not exist"); + return null; + } + ArrayList layerInfoList = new ArrayList(); + O2LayerInfo lInfo = null; + BufferedReader bReader = null; + try { + bReader = new BufferedReader(new FileReader(conf)); + String line; + while ((line = bReader.readLine()) != null) { + line = line.trim(); + if (line.startsWith("#") || ServerUtil.isNullString(line)) + continue; + try { + if (line.equalsIgnoreCase("[LAYER_CONFIG]")) { + lInfo = new O2LayerInfo(); + continue; + } + if (line.toUpperCase().contains("LAYER.ACTIVATE")) { + lInfo.setActivate(line.split("\\=")[1]); + continue; + } + if (line.toUpperCase().contains("LAYER.NAME")) { + lInfo.setLayerName(line.split("\\=")[1]); + continue; + } + if (line.toUpperCase().contains("LAYER.CRS")) { + lInfo.setLayerCRS(line.split("\\=")[1]); + continue; + } + if (line.toUpperCase().contains("LAYER.PATH")) { + lInfo.setLayerPath(line.split("\\=")[1]); + continue; + } + if (line.toUpperCase().contains("LAYER.DESC")) { + lInfo.setDesc(line.split("\\=")[1]); + continue; + } + if (line.toUpperCase().contains("LAYER.DATA.MIN")) { + lInfo.setMinData(line.split("\\=")[1]); + continue; + } + if (line.toUpperCase().contains("LAYER.DATA.MAX")) { + lInfo.setMaxData(line.split("\\=")[1]); + continue; + } + if (line.toUpperCase().contains("LAYER.DATA.NODATA")) { + lInfo.setNoData(line.split("\\=")[1]); + continue; + } + if (line.equalsIgnoreCase("[/LAYER_CONFIG]")) { + if (lInfo != null && lInfo.isAvailable()) { + layerInfoList.add(lInfo); + } else { + LogMngr.getInstance().logError("[O2DEM]", + "[" + conf.getName() + "] Skip this O2DemLayer :: Layer info is not available [" + lInfo.getLayerName() + "]"); + } + lInfo = null; + } + } catch (Exception exception) {} + } + } catch (Exception e) { + LogMngr.getInstance().logError("[O2DEM]", + "[" + conf.getName() + "] O2DemLayer configuration file is not valid :: " + e.getMessage()); + return null; + } finally { + try { + if (bReader != null) { + bReader.close(); + bReader = null; + } + } catch (IOException e) { + bReader = null; + } + } + return layerInfoList; + } + + public static O2DemLayer addLayer(File layerPath, String layerName, CoordinateReferenceSystem crs, String desc, Float min, Float max, Float noData) throws Exception { + if (layerPath == null || + !layerPath.exists() || + layerPath.isFile()) + throw new IOException("O2DemLayer levelset is not exist [" + layerPath.getAbsolutePath() + "]"); + if (ServerUtil.isNullString(layerName)) + throw new IOException("O2DemLayer LayerName is null"); + if (crs == null) + throw new IOException("O2DemLayer LayerCRS is null"); + try { + O2LayerLevelSet lvlSet = O2LayerUtil.createLevelSet(LayerFactory.LayerType.O2DEM, layerPath); + if (min != null) + lvlSet.setMinData(min); + if (max != null) + lvlSet.setMaxData(max); + if (noData != null) + lvlSet.setNoData(noData); + AVList params = new AVList(); + params.setValue("conf.service.map.name", ServerContext.getMap().getName()); + params.setValue("conf.service.layer.name", layerName); + params.setValue("conf.service.ref.server", LayerFactory.LayerType.O2DEM.getType()); + params.setValue("conf.service.ref.source", layerPath.getParent()); + params.setValue("conf.service.ref.crs", crs); + params.setValue("conf.service.sld", null); + params.setValue("conf.service.use.cache", Boolean.valueOf(false)); + params.setValue("conf.service.last.update", null); + params.setValue("conf.service.description", desc); + params.setValue("o2layer.conf.level.set", lvlSet); + Layer layer = LayerFactory.createLayer(LayerFactory.LayerType.O2DEM, params); + ServerContext.getMap().getServiceLayerSet().addLayer(layer, false); + return (O2DemLayer)layer; + } catch (Exception e) { + throw e; + } + } + + public static synchronized void reloadLayer() throws Exception { + ArrayList oldLayers = ServerContext.getMap().getServiceLayerSet().removeLayer(LayerFactory.LayerType.O2DEM); + try { + initLayers(); + LogMngr.getInstance().logInfo("[O2DEM]", "Success to reload O2DemLayers."); + } catch (Exception e) { + LogMngr.getInstance().logError("[O2DEM]", "Fail to reload O2DemLayers. Now use previous O2DemLayers :: " + e); + ServerContext.getMap().getServiceLayerSet().addLayers(oldLayers, false); + throw e; + } + } +} diff --git a/src/main/java/com/geotwo/webserver/core/coverage/O2ImgLayerMngr.java b/src/main/java/com/geotwo/webserver/core/coverage/O2ImgLayerMngr.java new file mode 100644 index 0000000..83a6535 --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/coverage/O2ImgLayerMngr.java @@ -0,0 +1,169 @@ +package com.geotwo.webserver.core.coverage; + +import com.geotwo.webserver.core.ServerContext; +import com.geotwo.webserver.core.coverage.o2layer.O2LayerInfo; +import com.geotwo.webserver.core.coverage.o2layer.O2LayerLevelSet; +import com.geotwo.webserver.core.coverage.o2layer.O2LayerUtil; +import com.geotwo.webserver.core.log.LogMngr; +import com.geotwo.webserver.core.map.LayerFactory; +import com.geotwo.webserver.core.map.layer.Layer; +import com.geotwo.webserver.core.map.layer.O2ImgLayer; +import com.geotwo.webserver.core.util.AVList; +import com.geotwo.webserver.core.util.ServerUtil; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import org.opengis.referencing.crs.CoordinateReferenceSystem; + +public class O2ImgLayerMngr { + public static void initLayers() { + try { + File dir = ServerContext.getPluginsFolder(); + String fileName = String.valueOf(ServerContext.getMap().getName()) + LayerFactory.LayerType.O2IMG.getPrefix(); + File confFile = ServerUtil.findFile(dir, fileName); + if (confFile == null) { + LogMngr.getInstance().logError("[O2IMG]", + "Skip create O2ImgLayer :: Layer Configuration File [" + confFile + "] is not exist"); + return; + } + LogMngr.getInstance().logDebug("[O2IMG]", + "[" + confFile.getName() + "] Now create O2ImgLayer from this configuration"); + ArrayList layerInfoList = parseO2ImgLayer(confFile); + if (layerInfoList == null || layerInfoList.isEmpty()) { + LogMngr.getInstance().logError("[O2IMG]", + "[" + confFile.getName() + "] Fail to create O2ImgLayer :: O2ImgLayer size is ZERO[0] from this configuration"); + return; + } + for (O2LayerInfo info : layerInfoList) { + LogMngr.getInstance().logDebug("[O2IMG]", + "[" + confFile.getName() + "][" + info.getLayerName() + "] Now create this O2ImgLayer"); + try { + addLayer(info.getLayerPath(), info.getLayerName(), info.getLayerCRS(), info.getDesc()); + LogMngr.getInstance().logInfo("[O2IMG]", + "[" + confFile.getName() + "][" + info.getLayerName() + "] Add Layer Success :: " + + "[Map:" + ServerContext.getMap().getName() + "/Layer:" + info.getLayerName() + "] : " + + "[RefServer:" + LayerFactory.LayerType.O2IMG.getType() + "/RefSource:" + info.getLayerPath() + "]"); + } catch (Exception e) { + LogMngr.getInstance().logError("[O2IMG]", + "[" + confFile.getName() + "][" + info.getLayerName() + "] Add Layer Fail :: " + e); + } + LogMngr.getInstance().logDebug("[O2IMG]", ""); + } + } catch (Exception e) { + LogMngr.getInstance().logError("[O2IMG]", "Create O2ImgLayer Fail :: " + e); + } + } + + private static ArrayList parseO2ImgLayer(File conf) { + if (!conf.exists()) { + LogMngr.getInstance().logError("[O2IMG]", + "[" + conf.getName() + "] Create O2ImgLayer Fail :: O2ImgLayer configuration is not exist"); + return null; + } + ArrayList layerInfoList = new ArrayList(); + O2LayerInfo lInfo = null; + BufferedReader bReader = null; + try { + bReader = new BufferedReader(new FileReader(conf)); + String line; + while ((line = bReader.readLine()) != null) { + line = line.trim(); + if (line.startsWith("#") || ServerUtil.isNullString(line)) + continue; + try { + if (line.equalsIgnoreCase("[LAYER_CONFIG]")) { + lInfo = new O2LayerInfo(); + continue; + } + if (line.toUpperCase().contains("LAYER.ACTIVATE")) { + lInfo.setActivate(line.split("\\=")[1]); + continue; + } + if (line.toUpperCase().contains("LAYER.NAME")) { + lInfo.setLayerName(line.split("\\=")[1]); + continue; + } + if (line.toUpperCase().contains("LAYER.CRS")) { + lInfo.setLayerCRS(line.split("\\=")[1]); + continue; + } + if (line.toUpperCase().contains("LAYER.PATH")) { + lInfo.setLayerPath(line.split("\\=")[1]); + continue; + } + if (line.toUpperCase().contains("LAYER.DESC")) { + lInfo.setDesc(line.split("\\=")[1]); + continue; + } + if (line.equalsIgnoreCase("[/LAYER_CONFIG]")) { + if (lInfo != null && lInfo.isAvailable()) { + layerInfoList.add(lInfo); + } else { + LogMngr.getInstance().logError("[O2IMG]", + "[" + conf.getName() + "] Skip this O2ImgLayer :: Layer info is not available [" + lInfo.getLayerName() + "]"); + } + lInfo = null; + } + } catch (Exception exception) {} + } + } catch (Exception e) { + LogMngr.getInstance().logError("[O2IMG]", + "[" + conf.getName() + "] O2ImgLayer configuration file is not valid :: " + e.getMessage()); + return null; + } finally { + try { + if (bReader != null) { + bReader.close(); + bReader = null; + } + } catch (IOException e) { + bReader = null; + } + } + return layerInfoList; + } + + public static O2ImgLayer addLayer(File layerPath, String layerName, CoordinateReferenceSystem crs, String desc) throws Exception { + if (layerPath == null || + !layerPath.exists() || + layerPath.isFile()) + throw new IOException("O2ImgLayer levelset is not exist [" + layerPath.getAbsolutePath() + "]"); + if (ServerUtil.isNullString(layerName)) + throw new IOException("O2ImgLayer LayerName is null"); + if (crs == null) + throw new IOException("O2ImgLayer LayerCRS is null"); + try { + O2LayerLevelSet lvlSet = O2LayerUtil.createLevelSet(LayerFactory.LayerType.O2IMG, layerPath); + AVList params = new AVList(); + params.setValue("conf.service.map.name", ServerContext.getMap().getName()); + params.setValue("conf.service.layer.name", layerName); + params.setValue("conf.service.ref.server", LayerFactory.LayerType.O2IMG.getType()); + params.setValue("conf.service.ref.source", layerPath.getParent()); + params.setValue("conf.service.ref.crs", crs); + params.setValue("conf.service.sld", null); + params.setValue("conf.service.use.cache", Boolean.valueOf(false)); + params.setValue("conf.service.last.update", null); + params.setValue("conf.service.description", desc); + params.setValue("o2layer.conf.level.set", lvlSet); + Layer layer = LayerFactory.createLayer(LayerFactory.LayerType.O2IMG, params); + ServerContext.getMap().getServiceLayerSet().addLayer(layer, false); + return (O2ImgLayer)layer; + } catch (Exception e) { + throw e; + } + } + + public static synchronized void reloadLayer() throws Exception { + ArrayList oldLayers = ServerContext.getMap().getServiceLayerSet().removeLayer(LayerFactory.LayerType.O2IMG); + try { + initLayers(); + LogMngr.getInstance().logInfo("[O2IMG]", "Success to reload O2ImgLayers."); + } catch (Exception e) { + LogMngr.getInstance().logError("[O2IMG]", "Fail to reload O2ImgLayers. Now use previous O2ImgLayers :: " + e); + ServerContext.getMap().getServiceLayerSet().addLayers(oldLayers, false); + throw e; + } + } +} diff --git a/src/main/java/com/geotwo/webserver/core/coverage/WpsCovStoreMngr.java b/src/main/java/com/geotwo/webserver/core/coverage/WpsCovStoreMngr.java new file mode 100644 index 0000000..ecfdb70 --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/coverage/WpsCovStoreMngr.java @@ -0,0 +1,74 @@ +package com.geotwo.webserver.core.coverage; + +import com.geotwo.webserver.core.ServerContext; +import com.geotwo.webserver.core.coverage.o2layer.O2LayerLevelSet; +import com.geotwo.webserver.core.coverage.o2layer.O2LayerUtil; +import com.geotwo.webserver.core.log.LogMngr; +import com.geotwo.webserver.core.map.LayerFactory; +import com.geotwo.webserver.core.map.layer.Layer; +import com.geotwo.webserver.core.map.layer.O2DemLayer; +import com.geotwo.webserver.core.util.AVList; +import com.geotwo.webserver.core.util.ServerUtil; +import com.geotwo.webserver.core.vector.WpsVecStoreMngr; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import org.opengis.referencing.crs.CoordinateReferenceSystem; + +public class WpsCovStoreMngr { + public static void initLayers() {} + + public static O2DemLayer addLayer(File layerPath, String layerName, String layerType, CoordinateReferenceSystem crs, String hashTag, String desc, String authorId, WpsVecStoreMngr.O2WpsMetaTableType metaTblType, Float min, Float max, Float noData) throws Exception { + if (layerPath == null || + !layerPath.exists() || + layerPath.isFile()) + throw new IOException("O2WPSCOVLayer levelset is not exist [" + layerPath.getAbsolutePath() + "]"); + if (ServerUtil.isNullString(layerName)) + throw new IOException("O2WPSCOVLayer LayerName is null"); + if (crs == null) + throw new IOException("O2WPSCOVLayer LayerCRS is null"); + try { + O2LayerLevelSet lvlSet = O2LayerUtil.createLevelSet(LayerFactory.LayerType.O2DEM, layerPath); + lvlSet.setMinData(min); + lvlSet.setMaxData(max); + lvlSet.setNoData(noData); + AVList params = new AVList(); + params.setValue("conf.service.map.name", ServerContext.getMap().getName()); + params.setValue("conf.service.layer.name", layerName); + params.setValue("conf.service.ref.server", LayerFactory.LayerType.O2DEM.getType()); + params.setValue("conf.service.ref.source", layerPath.getParent()); + params.setValue("conf.service.o2wps.source.path", layerPath.toString()); + params.setValue("conf.service.ref.crs", crs); + params.setValue("conf.service.sld", null); + params.setValue("conf.service.use.cache", Boolean.valueOf(false)); + params.setValue("conf.service.o2wps.hashtag", hashTag); + params.setValue("conf.service.description", desc); + params.setValue("conf.service.o2wps.source.type", "o2i"); + if (authorId == null) { + params.setValue("conf.service.o2wps.author.id", "Anonymous"); + } else { + params.setValue("conf.service.o2wps.author.id", authorId); + } + params.setValue("o2layer.conf.level.set", lvlSet); + Layer layer = LayerFactory.createLayer(LayerFactory.LayerType.O2WPSCOV, params); + ServerContext.getMap().getO2WpsLayerSet().addLayer(metaTblType.getName(), layer); + return (O2DemLayer)layer; + } catch (Exception e) { + throw e; + } + } + + public static synchronized void reloadLayer() throws Exception { + ArrayList oldLayers = ServerContext.getMap().getO2WpsLayerSet().removeLayer(LayerFactory.LayerType.O2WPSCOV); + try { + initLayers(); + LogMngr.getInstance().logInfo("[O2WPS]", "Success to reload O2DemLayers."); + } catch (Exception e) { + LogMngr.getInstance().logError("[O2WPS]", "Fail to reload O2DemLayers. Now use previous O2DemLayers :: " + e); + ServerContext.getMap().getO2WpsLayerSet().addLayers(oldLayers, false); + throw e; + } + } + + public static void deleteCoverageFiles(File fileName) {} +} diff --git a/src/main/java/com/geotwo/webserver/core/coverage/o2layer/O2LayerIndex.java b/src/main/java/com/geotwo/webserver/core/coverage/o2layer/O2LayerIndex.java new file mode 100644 index 0000000..c7b559b --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/coverage/o2layer/O2LayerIndex.java @@ -0,0 +1,47 @@ +package com.geotwo.webserver.core.coverage.o2layer; + +import com.vividsolutions.jts.geom.Envelope; + +public class O2LayerIndex +{ + Envelope bbox; + int row; + int col; + int blockIndex; + long filePosition; + + public O2LayerIndex(Envelope bbox, int row, int col) + { + this.bbox = bbox; + this.row = row; + this.col = col; + } + + public Envelope getBBox() { + return this.bbox; + } + + public int getRow() { + return this.row; + } + + public int getCol() { + return this.col; + } + + public void setBlockIndex(int idx) { + this.blockIndex = idx; + } + + public int getBlockIndex() { + return this.blockIndex; + } + + public void setFilePosition(long pos) { + this.filePosition = pos; + } + + public long getFilePosition() { + return this.filePosition; + } +} \ No newline at end of file diff --git a/src/main/java/com/geotwo/webserver/core/coverage/o2layer/O2LayerInfo.java b/src/main/java/com/geotwo/webserver/core/coverage/o2layer/O2LayerInfo.java new file mode 100644 index 0000000..9bb89a5 --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/coverage/o2layer/O2LayerInfo.java @@ -0,0 +1,131 @@ +package com.geotwo.webserver.core.coverage.o2layer; + +import com.geotwo.webserver.core.log.LogMngr; +import com.geotwo.webserver.core.util.ServerUtil; +import com.geotwo.webserver.core.vector.crs.CRSMngr; +import java.io.File; +import org.opengis.referencing.crs.CoordinateReferenceSystem; + +public class O2LayerInfo { + private String layerName; + + private boolean activate = false; + + private CoordinateReferenceSystem layerCRS; + + private File layerPath; + + private String desc; + + private Float minData = null; + + private Float maxData = null; + + private Float noData = null; + + public String getLayerName() { + return this.layerName; + } + + public boolean isActivate() { + return this.activate; + } + + public CoordinateReferenceSystem getLayerCRS() { + return this.layerCRS; + } + + public File getLayerPath() { + return this.layerPath; + } + + public void setLayerName(String name) { + if (ServerUtil.isNullString(name)) + this.layerName = null; + this.layerName = name.trim().toUpperCase(); + } + + public String getDesc() { + return this.desc; + } + + public void setActivate(String actiStr) { + this.activate = ServerUtil.getBooleanValue(actiStr); + } + + public void setLayerCRS(String crsName) { + this.layerCRS = CRSMngr.getCRS(crsName); + } + + public void setLayerPath(String path) { + if (ServerUtil.isNullString(path)) + return; + try { + File file = new File(path.trim()); + if (file.exists()) + this.layerPath = file; + } catch (Exception e) { + this.layerPath = null; + } + } + + public void setDesc(String desc) { + this.desc = desc; + } + + public void setMinData(String min) { + try { + this.minData = Float.valueOf(min); + } catch (Exception e) { + this.minData = null; + } + } + + public void setMaxData(String max) { + try { + this.maxData = Float.valueOf(max); + } catch (Exception e) { + this.maxData = null; + } + } + + public void setNoData(String no) { + try { + this.noData = Float.valueOf(no); + } catch (Exception e) { + this.noData = null; + } + } + + public Float getMinData() { + return this.minData; + } + + public Float getMaxData() { + return this.maxData; + } + + public Float getNoData() { + return this.noData; + } + + public boolean isAvailable() { + if (!this.activate) { + LogMngr.getInstance().logError("[LAYER]", "Layer info [layer.activate] is False"); + return false; + } + if (ServerUtil.isNullString(this.layerName)) { + LogMngr.getInstance().logError("[LAYER]", "Layer info [layer.name] is Empty"); + return false; + } + if (this.layerPath == null) { + LogMngr.getInstance().logError("[LAYER]", "Layer info [layer.path] is not exist"); + return false; + } + if (this.layerCRS == null) { + LogMngr.getInstance().logError("[LAYER]", "Layer info [layer.crs] is not available"); + return false; + } + return true; + } +} diff --git a/src/main/java/com/geotwo/webserver/core/coverage/o2layer/O2LayerLevel.java b/src/main/java/com/geotwo/webserver/core/coverage/o2layer/O2LayerLevel.java new file mode 100644 index 0000000..f11df39 --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/coverage/o2layer/O2LayerLevel.java @@ -0,0 +1,164 @@ +package com.geotwo.webserver.core.coverage.o2layer; + +import com.vividsolutions.jts.geom.Envelope; +import java.io.File; + +public class O2LayerLevel +{ + private final File levelPath; + private String version; + private String type; + private int level; + private Envelope bbox; + private double minZ; + private double maxZ; + private double resolutionX; + private double resolutionY; + private int totalPixelSizeX; + private int totalPixelSizeY; + private int tileCountX; + private int tileCountY; + private int tileSizeX; + private int tileSizeY; + private int blockCount; + private byte[] reserved = new byte[32]; + + public O2LayerLevel(File dir) throws Exception { + this.levelPath = dir; + } + + public File getLevelPath() { + return this.levelPath; + } + + void setVersion(String version) { + if (version.length() != 8) { + version = "O2I1.0.0"; + return; + } + + this.version = version.trim().toUpperCase(); + } + + public String getVersion() { + return this.version; + } + + void setType(String type) + { + if (type.length() != 8) { + type = "DEM/FLT "; + return; + } + + this.type = type.trim().toUpperCase(); + } + + public String getType() { + return this.type; + } + + void setLevel(int lvl) { + this.level = lvl; + } + + public int getLevel() { + return this.level; + } + + void setBBox(Envelope box) { + this.bbox = box; + } + + public Envelope getBBox() { + return this.bbox; + } + + void setZ(double min, double max) { + this.minZ = min; + this.maxZ = max; + } + + public double getMinZ() { + return this.minZ; + } + + public double getMaxZ() { + return this.maxZ; + } + + void setResolution(double x, double y) { + this.resolutionX = Math.abs(x); + this.resolutionY = Math.abs(y); + } + + public double getResolutionX() { + return this.resolutionX; + } + + public double getResolutionY() { + return this.resolutionY; + } + + void setTotalPixelSize(int x, int y) { + this.totalPixelSizeX = x; + this.totalPixelSizeY = y; + } + + public int getTotalPixelSizeX() { + return this.totalPixelSizeX; + } + + public int getTotalPixelSizeY() { + return this.totalPixelSizeY; + } + + void setTileCount(int x, int y) { + this.tileCountX = x; + this.tileCountY = y; + } + + public int getTileCountX() { + return this.tileCountX; + } + + public int getTileCountY() { + return this.tileCountY; + } + + void setTileSize(int x, int y) { + this.tileSizeX = x; + this.tileSizeY = y; + } + + public int getTileSizeX() { + return this.tileSizeX; + } + + public int getTileSizeY() { + return this.tileSizeY; + } + + void setBlockCount(int count) { + this.blockCount = count; + } + + public int getBlockCount() { + return this.blockCount; + } + + void setReserved(byte[] in) { + if ((in == null) || (in.length != this.reserved.length)) { + for (int i = 0; i < this.reserved.length; i++) { + this.reserved[i] = 0; + } + return; + } + + this.reserved = in; + } + + public byte[] getReserved() { + return this.reserved; + } +} \ No newline at end of file diff --git a/src/main/java/com/geotwo/webserver/core/coverage/o2layer/O2LayerLevelSet.java b/src/main/java/com/geotwo/webserver/core/coverage/o2layer/O2LayerLevelSet.java new file mode 100644 index 0000000..2fdb86b --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/coverage/o2layer/O2LayerLevelSet.java @@ -0,0 +1,98 @@ +package com.geotwo.webserver.core.coverage.o2layer; + +import com.geotwo.webserver.core.map.LayerFactory; +import com.vividsolutions.jts.geom.Envelope; +import java.io.File; +import java.util.TreeMap; + +public class O2LayerLevelSet { + private final File rootPath; + + private final LayerFactory.LayerType layerType; + + private Envelope bbox; + + TreeMap levels = new TreeMap(); + + private Float minData; + + private Float maxData; + + private Float noData; + + public O2LayerLevelSet(LayerFactory.LayerType type, File dir) { + this.layerType = type; + this.rootPath = dir; + } + + public File getRootPath() { + return this.rootPath; + } + + public LayerFactory.LayerType getLayerType() { + return this.layerType; + } + + void addLevel(O2LayerLevel level) { + this.levels.put(Integer.valueOf(level.getLevel()), level); + if (this.bbox == null) { + this.bbox = level.getBBox(); + } else { + this.bbox.expandToInclude(this.bbox); + } + } + + public O2LayerLevel getLevelByResolution(double res) { + O2LayerLevel level = null; + for (O2LayerLevel lvl : this.levels.values()) { + if (level == null) { + level = lvl; + continue; + } + if (Math.abs(level.getResolutionX() - res) > + Math.abs(lvl.getResolutionX() - res)) + level = lvl; + } + return level; + } + + public O2LayerLevel getLevelByIndex(int idx) { + return this.levels.get(Integer.valueOf(idx)); + } + + public O2LayerLevel getLevel(int idx) { + return (O2LayerLevel)this.levels.values().toArray()[idx]; + } + + public int size() { + return this.levels.size(); + } + + public Envelope getBBox() { + return this.bbox; + } + + public void setMinData(Float min) { + this.minData = min; + } + + public void setMaxData(Float max) { + this.maxData = max; + } + + public void setNoData(Float no) { + this.noData = no; + } + + public Float getMinData() { + return this.minData; + } + + public Float getMaxData() { + return this.maxData; + } + + public Float getNoData() { + return this.noData; + } +} diff --git a/src/main/java/com/geotwo/webserver/core/coverage/o2layer/O2LayerUtil.java b/src/main/java/com/geotwo/webserver/core/coverage/o2layer/O2LayerUtil.java new file mode 100644 index 0000000..abe0e58 --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/coverage/o2layer/O2LayerUtil.java @@ -0,0 +1,461 @@ +package com.geotwo.webserver.core.coverage.o2layer; + +import com.geotwo.webserver.core.log.LogMngr; +import com.geotwo.webserver.core.map.LayerFactory; +import com.geotwo.webserver.core.util.ServerUtil; +import com.vividsolutions.jts.geom.Envelope; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.RenderedImage; +import java.awt.image.WritableRaster; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileFilter; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.FileChannel; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import javax.imageio.ImageIO; +import javax.media.jai.RasterFactory; +import org.geotools.coverage.GridSampleDimension; +import org.geotools.coverage.grid.GridCoverage2D; +import org.geotools.coverage.grid.GridCoverageFactory; +import org.geotools.geometry.jts.ReferencedEnvelope; + +public class O2LayerUtil { + public static final String NODATA_PROPERTY_NAME = "GC_NODATA"; + + public static final String MINVALUE_PROPERTY_NAME = "GC_MINVALUE"; + + public static final String MAXVALUE_PROPERTY_NAME = "GC_MAXVALUE"; + + private static final int INDEX_HEADER_BYTE = 144; + + private static final int INDEX_TILEINFO_BYTE = 20; + + private static final GridCoverageFactory gcFactory = new GridCoverageFactory(); + + public static String readString(FileChannel fc, int capacity) throws Exception { + ByteBuffer byteData = ByteBuffer.allocate(capacity); + fc.read(byteData); + byteData.flip(); + String result = new String(byteData.order(ByteOrder.nativeOrder()).array()); + byteData.clear(); + byteData = null; + return result; + } + + public static int readInt(FileChannel fc) throws Exception { + ByteBuffer byteData = ByteBuffer.allocate(4); + fc.read(byteData); + byteData.flip(); + int result = byteData.order(ByteOrder.nativeOrder()).getInt(); + byteData.clear(); + byteData = null; + return result; + } + + public static double readDouble(FileChannel fc) throws Exception { + ByteBuffer byteData = ByteBuffer.allocate(8); + fc.read(byteData); + byteData.flip(); + double result = byteData.order(ByteOrder.nativeOrder()).getDouble(); + byteData.clear(); + byteData = null; + return result; + } + + public static O2LayerLevelSet createLevelSet(LayerFactory.LayerType type, File dir) throws Exception { + if (dir == null || + !dir.exists() || + dir.isFile()) + throw new IOException("O2ImgLayer or O2DemLayer dataset is not exist [" + dir.getAbsolutePath() + "]"); + if (type == null) + throw new IOException("O2ImgLayer or O2DemLayer type is Null"); + File[] levels = dir.listFiles(new FileFilter() { + String regex = "^LEVEL[0-9]+"; + + public boolean accept(File path) { + if (path.isDirectory() && + path.getName().toUpperCase().matches(this.regex)) + return true; + return false; + } + }); + O2LayerLevelSet lvlSet = new O2LayerLevelSet(type, dir); + findValueInfo(lvlSet); + LogMngr.getInstance().logDebug("[O2INDEX]", + "[" + dir.getName() + "] This layer has [" + levels.length + "] level. Now find index file for eatch level"); + byte b; + int i; + File[] arrayOfFile1; + for (i = (arrayOfFile1 = levels).length, b = 0; b < i; ) { + File level = arrayOfFile1[b]; + try { + O2LayerLevel idx = createLevel(type, level); + lvlSet.addLevel(idx); + LogMngr.getInstance().logDebug("[O2INDEX]", + "[" + dir.getName() + "] Success to add this Level [" + level.getName() + "]"); + } catch (Exception e) { + LogMngr.getInstance().logError("[O2INDEX]", + "[" + dir.getName() + "] Fail to add this Level [" + level.getName() + "] :: " + e); + } + b++; + } + if (lvlSet.size() == 0) + throw new IOException("[" + dir.getName() + "] This layer has no level."); + return lvlSet; + } + + private static void findValueInfo(O2LayerLevelSet lvlSet) throws Exception { + RandomAccessFile raf = null; + try { + File infoFile = new File(lvlSet.getRootPath(), "/info.o2img"); + LogMngr.getInstance().logDebug("[O2INFO]", + "Now find info.o2img for O2IMG & O2DEM from here [" + infoFile.getAbsolutePath() + "]"); + raf = new RandomAccessFile(infoFile, "r"); + raf.readLine(); + raf.readLine(); + String type = raf.readLine(); + type = type.trim().toUpperCase(); + if (lvlSet.getLayerType() == LayerFactory.LayerType.O2IMG) { + if (!type.equalsIgnoreCase("IMAGE")) + throw new Exception("This level is not O2IMG type"); + } else if (!type.equalsIgnoreCase("DEM")) { + throw new Exception("This level is not O2DEM type"); + } + raf.readLine(); + raf.readLine(); + raf.readLine(); + raf.readLine(); + raf.readLine(); + raf.readLine(); + raf.readLine(); + raf.readLine(); + String minmax = raf.readLine(); + if (minmax != null) { + String[] value = minmax.split("\\s+"); + lvlSet.setMinData(Float.valueOf(value[0])); + lvlSet.setMaxData(Float.valueOf(value[1])); + } + String nodata = raf.readLine(); + if (nodata != null) + lvlSet.setNoData(Float.valueOf(nodata)); + } catch (Exception e) { + LogMngr.getInstance().logError("[O2INFO]", + "Fail to find info now use default or user setting"); + } finally { + if (raf != null) + try { + raf.close(); + } catch (IOException iOException) {} + } + } + + private static O2LayerLevel createLevel(LayerFactory.LayerType type, File dir) throws Exception { + RandomAccessFile raf = null; + FileChannel channel = null; + try { + File idxFile = new File(dir, "/index.o2img"); + raf = new RandomAccessFile(idxFile, "r"); + channel = raf.getChannel(); + O2LayerLevel o2Level = new O2LayerLevel(dir); + o2Level.setVersion(readString(channel, 8)); + o2Level.setType(readString(channel, 8)); + if (type == LayerFactory.LayerType.O2IMG) { + if (!o2Level.getType().contains("IMG")) + throw new Exception("This level is not O2IMG type"); + } else if (!o2Level.getType().contains("DEM")) { + throw new Exception("This level is not O2DEM type"); + } + o2Level.setLevel(readInt(channel)); + double minx = readDouble(channel); + double maxx = readDouble(channel); + double miny = readDouble(channel); + double maxy = readDouble(channel); + o2Level.setBBox(new Envelope(minx, maxx, miny, maxy)); + double minz = readDouble(channel); + double maxz = readDouble(channel); + o2Level.setZ(minz, maxz); + double resX = readDouble(channel); + double resY = readDouble(channel); + o2Level.setResolution(resX, resY); + int tPixelSizeX = readInt(channel); + int tPixelSizeY = readInt(channel); + o2Level.setTotalPixelSize(tPixelSizeX, tPixelSizeY); + int tileCountY = readInt(channel); + int tileCountX = readInt(channel); + o2Level.setTileCount(tileCountX, tileCountY); + int tileSizeX = readInt(channel); + int tileSizeY = readInt(channel); + o2Level.setTileSize(tileSizeX, tileSizeY); + o2Level.setBlockCount(readInt(channel)); + return o2Level; + } catch (Exception e) { + throw e; + } finally { + if (channel != null && channel.isOpen()) + try { + channel.close(); + } catch (IOException iOException) {} + if (raf != null) + try { + raf.close(); + } catch (IOException iOException) {} + } + } + + public static BufferedImage getO2Img(File levelPath, int blockIdx, long bPos) throws Exception { + RandomAccessFile raf = null; + FileChannel channel = null; + ByteBuffer byteData = null; + ByteArrayInputStream inStream = null; + try { + File blockFile = new File(levelPath, "/block" + blockIdx + ".o2blk"); + raf = new RandomAccessFile(blockFile, "r"); + channel = raf.getChannel(); + channel.position(bPos); + int size = readInt(channel); + raf.skipBytes(8); + byteData = ByteBuffer.allocate(size - 12); + channel.read(byteData); + byteData.flip(); + inStream = new ByteArrayInputStream(byteData.order(ByteOrder.nativeOrder()).array()); + BufferedImage bImage = ImageIO.read(inStream); + return bImage; + } catch (Exception e) { + LogMngr.getInstance().logError("[O2IMG]", "[O2LayerUtil] getO2Img fail :: " + e); + throw e; + } finally { + if (channel != null && channel.isOpen()) + try { + channel.close(); + } catch (IOException iOException) {} + if (raf != null) + try { + raf.close(); + } catch (IOException iOException) {} + if (byteData != null) { + byteData.clear(); + byteData = null; + } + if (inStream != null) { + inStream.close(); + inStream = null; + } + } + } + + public static float[][] getO2Dem(File levelPath, int blockIdx, long bPos, int width, int height, Float min, Float max, Float noData) throws Exception { + RandomAccessFile raf = null; + FileChannel channel = null; + ByteBuffer byteData = null; + ByteArrayInputStream inStream = null; + try { + File blockFile = new File(levelPath, "/block" + blockIdx + ".o2blk"); + raf = new RandomAccessFile(blockFile, "r"); + channel = raf.getChannel(); + channel.position(bPos); + int size = readInt(channel); + int matrixSize = size - 12; + raf.skipBytes(8); + byteData = ByteBuffer.allocate(matrixSize); + channel.read(byteData); + byteData.flip(); + inStream = new ByteArrayInputStream(byteData.array()); + float[][] data = new float[height][width]; + byte[] read = new byte[4]; + if (noData == null) + noData = Float.valueOf(Float.NaN); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + inStream.read(read); + float dem = ByteBuffer.wrap(read).order(ByteOrder.nativeOrder()).getFloat(); + if (min != null && dem < min.floatValue()) { + data[y][x] = noData.floatValue(); + } else if (max != null && max.floatValue() < dem) { + data[y][x] = noData.floatValue(); + } else { + data[y][x] = dem; + } + } + } + return data; + } catch (Exception e) { + LogMngr.getInstance().logError("[O2IMG]", "[O2LayerUtil] getO2Img fail :: " + e); + throw e; + } finally { + if (channel != null && channel.isOpen()) + try { + channel.close(); + } catch (IOException iOException) {} + if (raf != null) + try { + raf.close(); + } catch (IOException iOException) {} + if (byteData != null) { + byteData.clear(); + byteData = null; + } + if (inStream != null) { + inStream.close(); + inStream = null; + } + } + } + + public static BufferedImage getMap(O2LayerLevelSet levelSet, ReferencedEnvelope bbox, int width, int height) throws Exception { + BufferedImage image = new BufferedImage(width, height, 6); + Envelope targetBBox = bbox.intersection(levelSet.getBBox()); + if (targetBBox == null || targetBBox.isNull()) + return image; + double resX = bbox.getWidth() / width; + double resY = bbox.getHeight() / height; + double res = Math.max(resX, resY); + O2LayerLevel level = levelSet.getLevelByResolution(res); + ArrayList idxs = calBlockIndex(level, (Envelope)bbox); + Graphics2D graphics = image.createGraphics(); + for (O2LayerIndex idx : idxs) { + BufferedImage o2img = getO2Img(level.getLevelPath(), idx.getBlockIndex(), idx.getFilePosition()); + Rectangle tileArea = ServerUtil.calPaintArea(new Rectangle(width, height), (Envelope)bbox, idx.getBBox()); + int startX = (tileArea.x < 0) ? 0 : tileArea.x; + int startY = (tileArea.y < 0) ? 0 : tileArea.y; + int endX = (tileArea.getMaxX() > width) ? width : (int)tileArea.getMaxX(); + int endY = (tileArea.getMaxY() > height) ? height : (int)tileArea.getMaxY(); + double scaleX = level.getTileSizeX() / tileArea.width; + double scaleY = level.getTileSizeY() / tileArea.height; + graphics.drawImage(o2img, + startX, startY, endX, endY, + (int)(Math.abs(tileArea.x - startX) * scaleX), + (int)(Math.abs(tileArea.y - startY) * scaleY), + (int)(Math.abs(tileArea.x - endX) * scaleX), + (int)(Math.abs(tileArea.y - endY) * scaleY), + null); + } + return image; + } + + public static GridCoverage2D getCoverage(O2LayerLevelSet levelSet, ReferencedEnvelope bbox, int width, int height) throws Exception { + WritableRaster raster = + RasterFactory.createBandedRaster(4, width, height, 1, new Point(0, 0)); + Float noData = levelSet.getNoData(); + if (noData == null) + noData = Float.valueOf(Float.NaN); + for (int c = 0; c < width; c++) { + for (int r = 0; r < height; r++) + raster.setSample(c, r, 0, noData.floatValue()); + } + Envelope targetBBox = bbox.intersection(levelSet.getBBox()); + if (targetBBox == null || targetBBox.isNull()) + return gcFactory.create("DEM", raster, (Envelope)bbox); + double resX = bbox.getWidth() / width; + double resY = bbox.getHeight() / height; + double res = Math.max(resX, resY); + O2LayerLevel level = levelSet.getLevelByResolution(res); + ArrayList idxs = calBlockIndex(level, (Envelope)bbox); + for (O2LayerIndex idx : idxs) { + float[][] o2dem = getO2Dem( + level.getLevelPath(), idx.getBlockIndex(), idx.getFilePosition(), + level.getTileSizeX() + 1, level.getTileSizeY() + 1, + levelSet.getMinData(), levelSet.getMaxData(), noData); + Rectangle tileArea = ServerUtil.calPaintArea(new Rectangle(width, height), (Envelope)bbox, idx.getBBox()); + int startX = (tileArea.x < 0) ? 0 : tileArea.x; + int startY = (tileArea.y < 0) ? 0 : tileArea.y; + int endX = (tileArea.getMaxX() > width) ? width : (int)tileArea.getMaxX(); + int endY = (tileArea.getMaxY() > height) ? height : (int)tileArea.getMaxY(); + double scaleX = (level.getTileSizeX() + 1) / tileArea.width; + double scaleY = (level.getTileSizeY() + 1) / tileArea.height; + for (int row = startY; row < endY; row++) { + for (int col = startX; col < endX; col++) { + int getRow = (int)(Math.abs(tileArea.y - row) * scaleY); + int getCol = (int)(Math.abs(tileArea.x - col) * scaleX); + int size = 1; + float avr = o2dem[getRow][getCol]; + if (getRow - 1 >= 0) { + avr += o2dem[getRow - 1][getCol]; + size++; + } + if (getRow + 1 < level.getTileSizeY() + 1) { + avr += o2dem[getRow + 1][getCol]; + size++; + } + if (getCol - 1 >= 0) { + avr += o2dem[getRow][getCol - 1]; + size++; + } + if (getCol + 1 < level.getTileSizeX() + 1) { + avr += o2dem[getRow][getCol + 1]; + size++; + } + raster.setSample(col, row, 0, avr / size); + } + } + } + Map propMap = new HashMap(); + propMap.put("GC_MINVALUE", levelSet.getMinData()); + propMap.put("GC_MAXVALUE", levelSet.getMaxData()); + propMap.put("GC_NODATA", levelSet.getNoData()); + GridSampleDimension[] bands = new GridSampleDimension[raster.getNumBands()]; + ColorModel model = bands[0].getColorModel(0, bands.length, raster.getSampleModel().getDataType()); + RenderedImage image = new BufferedImage(model, raster, false, null); + return (new GridCoverageFactory()).create("DEM", image, (Envelope)bbox, null, null, propMap); + } + + public static ArrayList calBlockIndex(O2LayerLevel level, Envelope cBBox) throws Exception { + ArrayList result = new ArrayList(); + Envelope pBBox = level.getBBox(); + double width = level.getTileSizeX() * level.getResolutionX(); + double height = level.getTileSizeY() * level.getResolutionY(); + int nROffX = (int)((cBBox.getMinX() - pBBox.getMinX()) / level.getResolutionX()); + int nROffY = (int)((pBBox.getMaxY() - cBBox.getMaxY()) / level.getResolutionY()); + int nRWidth = (int)((cBBox.getMaxX() - pBBox.getMinX()) / level.getResolutionX()) - nROffX + 1; + int nRHeight = (int)((pBBox.getMaxY() - cBBox.getMinY()) / level.getResolutionY()) - nROffY + 1; + int sCol = nROffX / level.getTileSizeX(); + int eCol = (nROffX + nRWidth) / level.getTileSizeX(); + int sRow = nROffY / level.getTileSizeY(); + int eRow = (nROffY + nRHeight) / level.getTileSizeY(); + sCol = (sCol < 0) ? 0 : sCol; + eCol = (level.getTileCountX() <= eCol) ? (level.getTileCountX() - 1) : eCol; + sRow = (sRow < 0) ? 0 : sRow; + eRow = (level.getTileCountY() <= eRow) ? (level.getTileCountY() - 1) : eRow; + RandomAccessFile raf = null; + FileChannel channel = null; + try { + File idxFile = new File(level.getLevelPath(), "/index.o2img"); + raf = new RandomAccessFile(idxFile, "r"); + channel = raf.getChannel(); + for (int r = sRow; r <= eRow; r++) { + for (int c = sCol; c <= eCol; c++) { + Envelope bbox = new Envelope( + pBBox.getMinX() + width * c, + pBBox.getMinX() + width * (c + 1), + pBBox.getMaxY() - height * (r + 1), + pBBox.getMaxY() - height * r); + O2LayerIndex idx = new O2LayerIndex(bbox, r, c); + channel.position((144 + ( + level.getTileCountX() * r + c) * 20)); + idx.setBlockIndex(readInt(channel)); + idx.setFilePosition(readInt(channel)); + result.add(idx); + } + } + } finally { + if (channel != null && channel.isOpen()) + try { + channel.close(); + } catch (IOException iOException) {} + if (raf != null) + try { + raf.close(); + } catch (IOException iOException) {} + } + return result; + } +} diff --git a/src/main/java/com/geotwo/webserver/core/feature/FeatureMngr.java b/src/main/java/com/geotwo/webserver/core/feature/FeatureMngr.java new file mode 100644 index 0000000..a28bb34 --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/feature/FeatureMngr.java @@ -0,0 +1,1195 @@ +package com.geotwo.webserver.core.feature; + +import com.geotwo.webserver.core.ServerContext; +import com.geotwo.webserver.core.init.ConnMngr; +import com.geotwo.webserver.core.log.LogMngr; +import com.geotwo.webserver.core.map.LayerFactory; +import com.geotwo.webserver.core.map.layer.FeatureLayer; +import com.geotwo.webserver.core.map.layer.Layer; +import com.geotwo.webserver.core.util.ServerUtil; +import com.geotwo.webserver.core.vector.O2DSMngr; +import com.geotwo.webserver.core.vector.jdbc.O2SqlDialect; +import com.geotwo.webserver.core.vector.jdbc.ns.NonSpatialDialect; +import com.geotwo.webserver.core.vector.jdbc.oracle.OracleDialect; +import com.vividsolutions.jts.geom.Envelope; +import com.vividsolutions.jts.geom.Geometry; +import java.io.IOException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import org.geotools.data.DefaultTransaction; +import org.geotools.data.FeatureLock; +import org.geotools.data.FeatureLockException; +import org.geotools.data.FeatureReader; +import org.geotools.data.FeatureWriter; +import org.geotools.data.LockingManager; +import org.geotools.data.Query; +import org.geotools.data.Transaction; +import org.geotools.data.simple.SimpleFeatureCollection; +import org.geotools.data.simple.SimpleFeatureIterator; +import org.geotools.data.simple.SimpleFeatureSource; +import org.geotools.data.store.ContentFeatureStore; +import org.geotools.factory.Hints; +import org.geotools.feature.DefaultFeatureCollection; +import org.geotools.feature.simple.SimpleFeatureBuilder; +import org.geotools.feature.simple.SimpleFeatureImpl; +import org.geotools.feature.simple.SimpleFeatureTypeBuilder; +import org.geotools.filter.identity.FeatureIdImpl; +import org.geotools.filter.identity.GmlObjectIdImpl; +import org.geotools.geometry.jts.JTS; +import org.geotools.geometry.jts.ReferencedEnvelope; +import org.geotools.jdbc.JDBCFeatureReader; +import org.geotools.jdbc.JDBCFeatureStore; +import org.geotools.jdbc.PreparedStatementSQLDialect; +import org.geotools.jdbc.PrimaryKey; +import org.geotools.jdbc.PrimaryKeyColumn; +import org.geotools.jdbc.ResultSetFeatureRefinder; +import org.geotools.jdbc.SQLDialect; +import org.geotools.referencing.CRS; +import org.opengis.feature.simple.SimpleFeature; +import org.opengis.feature.simple.SimpleFeatureType; +import org.opengis.feature.type.AttributeDescriptor; +import org.opengis.feature.type.PropertyDescriptor; +import org.opengis.filter.Filter; +import org.opengis.filter.Id; +import org.opengis.filter.identity.FeatureId; +import org.opengis.filter.identity.GmlObjectId; +import org.opengis.referencing.crs.CoordinateReferenceSystem; +import org.opengis.referencing.operation.MathTransform; + +public class FeatureMngr { + public static final int DEFAULT_BATCH_SIZE = 1000; + + public static final String FEATURE_LOCK_ID = "LockFeatureId"; + + public static final String FEATURE_LOCK_RESULT = "LockFeatureResult"; + + private static final ConcurrentHashMap lockStore = new ConcurrentHashMap(); + + public static SimpleFeatureSource getFeatureSourceByLayer(String layerName) throws Exception { + try { + Layer layer = ServerContext.getMap().getLayer(layerName); + if (!(layer instanceof FeatureLayer)) + throw new NullPointerException("Layer [" + layerName + "] is not FeatureLayer."); + FeatureLayer fLayer = (FeatureLayer)layer; + return O2DSMngr.getFeatureSource(fLayer.getLayerType(), fLayer.getServerName(), fLayer.getSourceName()); + } catch (Exception e) { + throw new NullPointerException("Layer [" + layerName + "] is not exist."); + } + } + + public static SimpleFeatureCollection getFeatureCollection(LayerFactory.LayerType layerType, String serverName, Query query) throws Exception { + SimpleFeatureSource featureSource = O2DSMngr.getFeatureSource(layerType, serverName, query.getTypeName()); + query = QueryMngr.reFineQuery((SimpleFeatureType)featureSource.getSchema(), query); + return featureSource.getFeatures(query); + } + + public static O2FeatureCollection getFeatureCollectionByLayer(Query query) throws Exception { + Layer layer; + String typeName = query.getTypeName(); + if (ServerUtil.isNullString(typeName)) + throw new NullPointerException("TypeName is Null"); + try { + layer = ServerContext.getMap().getLayer(typeName); + if (!(layer instanceof FeatureLayer)) + throw new NullPointerException("Layer [" + typeName + "] is not FeatureLayer."); + } catch (Exception e) { + throw new NullPointerException("Layer [" + typeName + "] is not exist."); + } + FeatureLayer fLayer = (FeatureLayer)layer; + query.setTypeName(fLayer.getSourceName()); + SimpleFeatureCollection collection = getFeatureCollection(fLayer.getLayerType(), fLayer.getServerName(), query); + if (fLayer.getName().equalsIgnoreCase(fLayer.getSourceName())) + return new O2FeatureCollection(collection, null); + SimpleFeatureType newType = retypeFeatureType((SimpleFeatureType)collection.getSchema(), fLayer.getName()); + return new O2FeatureCollection(collection, newType); + } + + public static SimpleFeature getGmlObject(LayerFactory.LayerType layerType, String serverName, GmlObjectId id, Hints hints) throws Exception { + return O2DSMngr.getGmlObject(layerType, serverName, id, hints); + } + + public static SimpleFeature getGmlObjectByLayer(GmlObjectId id, Hints hints) throws IOException { + try { + Layer layer; + String layerName = id.getID().substring(0, id.getID().lastIndexOf(".")); + String objectID = id.getID().substring(id.getID().lastIndexOf(".") + 1); + try { + layer = ServerContext.getMap().getLayer(layerName); + if (!(layer instanceof FeatureLayer)) + throw new NullPointerException("Layer [" + layerName + "] is not FeatureLayer."); + } catch (Exception e) { + throw new NullPointerException("Layer [" + layerName + "] is not exist."); + } + FeatureLayer fLayer = (FeatureLayer)layer; + GmlObjectIdImpl gmlObjectIdImpl = new GmlObjectIdImpl(String.valueOf(fLayer.getSourceName()) + "." + objectID); + SimpleFeature feature = getGmlObject(fLayer.getLayerType(), fLayer.getServerName(), (GmlObjectId)gmlObjectIdImpl, hints); + SimpleFeatureType newType = retypeFeatureType(feature.getFeatureType(), fLayer.getName()); + SimpleFeatureBuilder fBuilder = new SimpleFeatureBuilder(newType); + fBuilder.init(feature); + return fBuilder.buildFeature(gmlObjectIdImpl.getID().replace(fLayer.getSourceName(), fLayer.getName())); + } catch (Exception e) { + throw new IOException(e.getMessage()); + } + } + + public static List insertFeature(LayerFactory.LayerType layerType, String serverName, String tableName, SimpleFeature feature, boolean useProvidedFid) throws Exception { + try { + JDBCFeatureStore featureStore = O2DSMngr.getFeatureStore(layerType, serverName, tableName); + SimpleFeatureType featureType = featureStore.getSchema(); + for (PropertyDescriptor property : feature.getFeatureType().getDescriptors()) { + if (featureType.getDescriptor(property.getName().getLocalPart().toUpperCase()) == null) + if (!property.getName().getLocalPart().equalsIgnoreCase("NAME") && + !property.getName().getLocalPart().equalsIgnoreCase("DESCRIPTION") && + !property.getName().getLocalPart().equalsIgnoreCase("BOUNDEDBY")) + throw new Exception("Input Property [" + property.getName().getLocalPart() + "] is not exist."); + } + if (useProvidedFid && + featureStore.getPrimaryKey() != null && + featureStore.getPrimaryKey().getColumns().size() != 0) { + String pkColumn = ((PrimaryKeyColumn)featureStore.getPrimaryKey().getColumns().get(0)).getName(); + if (feature.getProperty(pkColumn) != null) { + Object pkValue = feature.getProperty(pkColumn).getValue(); + Id id = QueryMngr.filterFactory.id(new FeatureId[] { (FeatureId)new FeatureIdImpl(pkValue.toString()) }); + int count = featureStore.getCount(new Query(featureStore.getSchema().getTypeName(), (Filter)id)); + if (count != 0) + throw new SQLException("Can't insert feature :: Already Exist PrimaryKey Value [" + feature.getIdentifier().getID() + "]"); + } + } + RefindInsertFeatureCollection refineFeatureCollection = + new RefindInsertFeatureCollection(feature, (ContentFeatureStore)featureStore, useProvidedFid); + List fID = null; + DefaultTransaction transaction = new DefaultTransaction("insert"); + try { + featureStore.setTransaction((Transaction)transaction); + FeatureWriter writer = featureStore.getWriter((Filter)Filter.INCLUDE, 1); + SimpleFeature toWrite = (SimpleFeature)writer.next(); + JDBCFeatureReader.ResultSetFeature resultSetFeature = ResultSetFeatureRefinder.refindResultSetFeature(toWrite); + fID = new LinkedList(); + SimpleFeatureIterator simpleFeatureIterator = refineFeatureCollection.features(); + try { + while (simpleFeatureIterator.hasNext()) { + SimpleFeature refineFeature = (SimpleFeature)simpleFeatureIterator.next(); + for (int i = 0; i < resultSetFeature.getType().getAttributeCount(); i++) { + String name = resultSetFeature.getType().getDescriptor(i).getLocalName(); + resultSetFeature.setAttribute(name, refineFeature.getAttribute(name)); + } + if (refineFeature.getUserData().size() > 0) + resultSetFeature.getUserData().putAll(refineFeature.getUserData()); + if (featureStore.getQueryCapabilities().isUseProvidedFIDSupported() && ( + (Boolean)refineFeature.getUserData().get(Hints.USE_PROVIDED_FID)).booleanValue()) + ((FeatureIdImpl)resultSetFeature.getIdentifier()).setID(refineFeature.getID()); + writer.write(); + fID.add(resultSetFeature.getIdentifier()); + } + } finally { + writer.close(); + simpleFeatureIterator.close(); + } + transaction.commit(); + } catch (Exception e) { + transaction.rollback(); + throw e; + } finally { + transaction.close(); + } + if (feature.getDefaultGeometry() != null || + feature.getDefaultGeometry() instanceof Geometry) { + Geometry insertGeom = (Geometry)feature.getDefaultGeometry(); + if (insertGeom.getUserData() != null && + insertGeom.getUserData() instanceof CoordinateReferenceSystem && + featureType.getCoordinateReferenceSystem() != null) { + CoordinateReferenceSystem crs = (CoordinateReferenceSystem)insertGeom.getUserData(); + if (!CRS.equalsIgnoreMetadata(crs, featureType.getCoordinateReferenceSystem())) { + MathTransform transform = CRS.findMathTransform(crs, featureType.getCoordinateReferenceSystem(), true); + insertGeom = JTS.transform(insertGeom, transform); + } + } + Envelope envelope = insertGeom.getEnvelopeInternal(); + onInsertMetaData(featureStore, fID, envelope); + } + LogMngr.getInstance().logInfo("[DB]", "Insert Success :: " + serverName + "/" + tableName + ">" + fID.toString()); + return fID; + } catch (Exception eek) { + LogMngr.getInstance().logInfo("[DB]", "Insert Fail :: " + eek); + throw new SQLException("Insert Fail :: " + eek); + } + } + + public static List insertFeatureCollection(LayerFactory.LayerType layerType, String serverName, String tableName, SimpleFeatureCollection collection, boolean useProvidedFid) throws Exception { + try { + JDBCFeatureStore featureStore = O2DSMngr.getFeatureStore(layerType, serverName, tableName); + SimpleFeatureType featureType = featureStore.getSchema(); + for (PropertyDescriptor property : ((SimpleFeatureType)collection.getSchema()).getDescriptors()) { + if (featureType.getDescriptor(property.getName().getLocalPart().toUpperCase()) == null) + if (!property.getName().getLocalPart().equalsIgnoreCase("NAME") && + !property.getName().getLocalPart().equalsIgnoreCase("DESCRIPTION") && + !property.getName().getLocalPart().equalsIgnoreCase("BOUNDEDBY")) + throw new Exception("Input Property [" + property.getName().getLocalPart() + "] is not exist."); + } + if (collection.isEmpty()) + throw new SQLException("Can't insert collection :: FeatureCollection is empty"); + RefindInsertFeatureCollection refineFeatureCollection = + new RefindInsertFeatureCollection(collection, (ContentFeatureStore)featureStore, useProvidedFid); + PrimaryKeyColumn pKeyCol = null; + PrimaryKey pKey = featureStore.getPrimaryKey(); + if (pKey != null && + pKey.getColumns().size() != 0) + pKeyCol = pKey.getColumns().get(0); + StringBuffer sql = new StringBuffer(); + sql.append("INSERT INTO "); + sql.append(featureType.getTypeName()); + sql.append(" ( "); + for (int i = 0; i < featureType.getAttributeCount(); i++) { + String colName = featureType.getDescriptor(i).getLocalName(); + if (pKeyCol == null || !pKeyCol.getName().equalsIgnoreCase(colName)) + sql.append(colName).append(","); + } + if (pKeyCol == null || pKeyCol instanceof org.geotools.jdbc.AutoGeneratedPrimaryKeyColumn) { + sql.setLength(sql.length() - 1); + } else { + sql.append(pKeyCol.getName()); + } + sql.append(" ) VALUES ( "); + for (AttributeDescriptor att : featureType.getAttributeDescriptors()) { + String colName = att.getLocalName(); + if (pKeyCol != null && pKeyCol.getName().equalsIgnoreCase(colName)) + continue; + sql.append("?").append(","); + } + if (pKeyCol == null || pKeyCol instanceof org.geotools.jdbc.AutoGeneratedPrimaryKeyColumn) { + sql.setLength(sql.length() - 1); + } else { + sql.append("?"); + } + sql.append(")"); + Double keyValue = Double.valueOf(0.0D); + if (pKeyCol != null && !(pKeyCol instanceof org.geotools.jdbc.AutoGeneratedPrimaryKeyColumn)) + keyValue = Double.valueOf(getMaxCount(featureStore, pKeyCol.getName())); + InsertParams iParams = new InsertParams(sql.toString(), keyValue); + DefaultTransaction transaction = new DefaultTransaction("batch insert"); + Connection cx = null; + SimpleFeatureIterator sfIter = null; + try { + featureStore.setTransaction((Transaction)transaction); + cx = featureStore.getDataStore().getConnection((Transaction)transaction); + DefaultFeatureCollection targetCollection = new DefaultFeatureCollection(); + int count = 0; + int idx = 0; + int size = collection.size(); + sfIter = collection.features(); + while (sfIter.hasNext()) { + SimpleFeatureImpl feature = (SimpleFeatureImpl)sfIter.next(); + count++; + targetCollection.add((SimpleFeature)feature); + if (count == 1000 || ( + !sfIter.hasNext() && count != 0)) { + idx++; + LogMngr.getInstance().logDebug("[DB]", + "QUERY : Batch insert by [" + (idx * 1000) + "/" + size + "] to " + + featureType.getTypeName()); + try { + onBatchInsert(cx, featureStore, targetCollection, iParams); + } catch (Exception e) { + transaction.rollback(); + LogMngr.getInstance().logError("[DB]", + "Fail add FeatureCollection use Batch Insert. Now try Single Insert"); + onSingleInsert(cx, featureStore, targetCollection, iParams); + } + transaction.commit(); + targetCollection.clear(); + count = 0; + } + } + } catch (Exception e) { + transaction.rollback(); + throw e; + } finally { + if (sfIter != null) + sfIter.close(); + transaction.close(); + featureStore.getDataStore().closeSafe(cx); + } + ReferencedEnvelope envelope = refineFeatureCollection.getBounds(); + if (envelope != null || !envelope.isNull()) { + CoordinateReferenceSystem crs = refineFeatureCollection.getSchema().getCoordinateReferenceSystem(); + if (crs != null) + if (!CRS.equalsIgnoreMetadata(crs, featureType.getCoordinateReferenceSystem())) { + MathTransform transform = CRS.findMathTransform(crs, featureType.getCoordinateReferenceSystem(), true); + envelope = ReferencedEnvelope.reference(JTS.transform((Envelope)envelope, transform)); + } + onInsertMetaData(featureStore, iParams.featureIDs, (Envelope)envelope); + } + LogMngr.getInstance().logInfo("[DB]", "Insert Collection Success :: " + serverName + "/" + tableName + " > " + iParams.featureIDs.size()); + return iParams.featureIDs; + } catch (Exception e) { + LogMngr.getInstance().logInfo("[DB]", "Insert Fail :: " + e); + throw new SQLException("Insert Fail :: " + e); + } + } + + private static InsertParams onBatchInsert(Connection cx, JDBCFeatureStore featureStore, DefaultFeatureCollection collection, InsertParams iParams) throws Exception { + List fID = new ArrayList(); + PreparedStatement ps = null; + try { + Double maxValue = iParams.maxValue; + Double keyValue = iParams.maxValue; + PrimaryKeyColumn pKeyCol = null; + PrimaryKey pKey = featureStore.getPrimaryKey(); + if (pKey != null && + pKey.getColumns().size() != 0) + pKeyCol = pKey.getColumns().get(0); + ps = cx.prepareStatement(iParams.sqlString); + SimpleFeatureIterator sfIter = collection.features(); + while (sfIter.hasNext()) { + SimpleFeatureImpl feature = (SimpleFeatureImpl)sfIter.next(); + keyValue = Double.valueOf(keyValue.doubleValue() + 1.0D); + boolean useExisting = Boolean.TRUE.equals(feature.getUserData().get(Hints.USE_PROVIDED_FID)); + if (useExisting) { + String eId = feature.getID(); + try { + keyValue = Double.valueOf(Double.parseDouble(eId.substring(eId.indexOf(".") + 1))); + } catch (Exception e) { + LogMngr.getInstance().logError("[DB]", + "PrimaryKey value is not number or null [" + eId + "] :: " + featureStore.getSchema().getTypeName()); + continue; + } + } else if (keyValue.doubleValue() <= maxValue.doubleValue()) { + keyValue = Double.valueOf(maxValue.doubleValue() + 1.0D); + } + if (keyValue.doubleValue() > maxValue.doubleValue()) + maxValue = keyValue; + addPreparedStatementValue(ps, feature, keyValue, featureStore, pKeyCol, cx); + ps.addBatch(); + fID.add(new FeatureIdImpl(String.valueOf(featureStore.getSchema().getTypeName()) + + "." + keyValue)); + } + sfIter.close(); + ps.executeBatch(); + iParams.maxValue = maxValue; + iParams.featureIDs.addAll(fID); + return iParams; + } finally { + featureStore.getDataStore().closeSafe(ps); + } + } + + private static InsertParams onSingleInsert(Connection cx, JDBCFeatureStore featureStore, DefaultFeatureCollection collection, InsertParams iParams) throws Exception { + List fID = new ArrayList(); + PreparedStatement ps = null; + try { + Double maxValue = iParams.maxValue; + Double keyValue = iParams.maxValue; + PrimaryKeyColumn pKeyCol = null; + PrimaryKey pKey = featureStore.getPrimaryKey(); + if (pKey != null && + pKey.getColumns().size() != 0) + pKeyCol = pKey.getColumns().get(0); + ps = cx.prepareStatement(iParams.sqlString); + SimpleFeatureIterator sfIter = collection.features(); + while (sfIter.hasNext()) { + SimpleFeatureImpl feature = (SimpleFeatureImpl)sfIter.next(); + keyValue = Double.valueOf(keyValue.doubleValue() + 1.0D); + boolean useExisting = Boolean.TRUE.equals(feature.getUserData().get(Hints.USE_PROVIDED_FID)); + if (useExisting) { + String eId = feature.getID(); + try { + keyValue = Double.valueOf(Double.parseDouble(eId.substring(eId.indexOf(".") + 1))); + } catch (Exception e) { + LogMngr.getInstance().logError("[DB]", + "PrimaryKey value is not number or null [" + eId + "] :: " + featureStore.getSchema().getTypeName()); + continue; + } + } else if (keyValue.doubleValue() <= maxValue.doubleValue()) { + keyValue = Double.valueOf(maxValue.doubleValue() + 1.0D); + } + if (keyValue.doubleValue() > maxValue.doubleValue()) + maxValue = keyValue; + try { + LogMngr.getInstance().logDebug("[DB]", + "QUERY : Single insert by [" + keyValue + " > " + feature + "] to " + + featureStore.getSchema().getTypeName()); + addPreparedStatementValue(ps, feature, keyValue, featureStore, pKeyCol, cx); + ps.execute(); + fID.add(new FeatureIdImpl(String.valueOf(featureStore.getSchema().getTypeName()) + + "." + keyValue)); + } catch (Exception e) { + LogMngr.getInstance().logError("[DB]", + "Fail add Feature use Single Insert. Skip this feature"); + } + } + sfIter.close(); + iParams.maxValue = maxValue; + iParams.featureIDs.addAll(fID); + } finally { + featureStore.getDataStore().closeSafe(ps); + } + return iParams; + } + + private static void addPreparedStatementValue(PreparedStatement ps, SimpleFeatureImpl feature, Double keyValue, JDBCFeatureStore featureStore, PrimaryKeyColumn pKeyCol, Connection cx) throws Exception { + PreparedStatementSQLDialect dialect = + (PreparedStatementSQLDialect)featureStore.getDataStore().getSQLDialect(); + int i = 1; + for (AttributeDescriptor att : featureStore.getSchema().getAttributeDescriptors()) { + String colName = att.getLocalName(); + if (pKeyCol != null && pKeyCol.getName().equalsIgnoreCase(colName)) + continue; + Class binding = att.getType().getBinding(); + Object value = feature.getAttribute(colName); + if (Geometry.class.isAssignableFrom(binding)) { + Geometry g = (Geometry)value; + dialect.setGeometryValue(g, 2, -1, binding, ps, i); + } else { + dialect.setValue(value, binding, ps, i, cx); + } + i++; + } + if (pKeyCol != null && !(pKeyCol instanceof org.geotools.jdbc.AutoGeneratedPrimaryKeyColumn)) + dialect.setValue(keyValue, pKeyCol.getType(), ps, i, cx); + } + + private static double getMaxCount(JDBCFeatureStore featureStore, String keyField) throws SQLException, IOException { + Connection cx = featureStore.getDataStore().getConnection(Transaction.AUTO_COMMIT); + Statement st = cx.createStatement(); + try { + String sql = "select max(" + keyField + ") from " + featureStore.getSchema().getTypeName(); + LogMngr.getInstance().logDebug("[DB]", "Lookup max count for [" + featureStore.getSchema().getTypeName() + "]"); + LogMngr.getInstance().logDebug("[DB]", "QUERY : " + sql); + } finally { + featureStore.getDataStore().closeSafe(cx); + featureStore.getDataStore().closeSafe(st); + } + } + + private static SimpleFeature refineInsertFeature(ContentFeatureStore featureStore, SimpleFeature feature) throws Exception { + SimpleFeatureType featureType = featureStore.getSchema(); + SimpleFeatureBuilder fBuilder = new SimpleFeatureBuilder(featureType); + String pkColumn = null; + if (featureStore instanceof JDBCFeatureStore) { + JDBCFeatureStore jdbcStore = (JDBCFeatureStore)featureStore; + if (jdbcStore.getPrimaryKey() != null && + jdbcStore.getPrimaryKey().getColumns().size() != 0) + pkColumn = ((PrimaryKeyColumn)jdbcStore.getPrimaryKey().getColumns().get(0)).getName(); + } + String newID = null; + for (AttributeDescriptor att : featureType.getAttributeDescriptors()) { + Object value = feature.getAttribute(att.getLocalName()); + if (value == null) + value = feature.getAttribute(att.getLocalName().toLowerCase()); + if (pkColumn != null && pkColumn.equalsIgnoreCase(att.getLocalName()) && value != null) + newID = value.toString(); + try { + if (value != null && Geometry.class.isAssignableFrom(value.getClass())) { + Geometry tGeom = (Geometry)value; + if (tGeom.getUserData() != null && tGeom.getUserData() instanceof CoordinateReferenceSystem) { + CoordinateReferenceSystem tCRS = (CoordinateReferenceSystem)tGeom.getUserData(); + if (!CRS.equalsIgnoreMetadata(featureType.getCoordinateReferenceSystem(), tCRS)) { + MathTransform transform = CRS.findMathTransform(tCRS, featureType.getCoordinateReferenceSystem(), true); + value = JTS.transform(tGeom, transform); + } + } + if (featureStore instanceof JDBCFeatureStore) { + JDBCFeatureStore jdbcStore = (JDBCFeatureStore)featureStore; + if (jdbcStore.getDataStore().getSQLDialect() instanceof OracleDialect) { + OracleDialect oDialect = (OracleDialect)jdbcStore.getDataStore().getSQLDialect(); + Integer srid = oDialect.getDBSrid(featureType.getTypeName(), featureType.getGeometryDescriptor().getLocalName()); + if (srid != null && srid.intValue() == 0) { + oDialect.getClass(); + ((Geometry)value).setUserData("OracleNullSrid"); + } + } + } + } + } catch (Exception e) { + throw new Exception("Fail to transform input geometry :: " + e); + } + fBuilder.set(att.getLocalName(), value); + } + SimpleFeature newFeature = fBuilder.buildFeature(newID); + if (feature.getUserData().size() > 0) + newFeature.getUserData().putAll(feature.getUserData()); + if (newID != null) + newFeature.getUserData().put(Hints.USE_PROVIDED_FID, Boolean.valueOf(true)); + return newFeature; + } + + private static void onInsertMetaData(JDBCFeatureStore featureStore, List fID, Envelope envelope) throws Exception { + DefaultTransaction transaction = new DefaultTransaction("insert meta"); + Connection cx = null; + try { + featureStore.setTransaction((Transaction)transaction); + cx = featureStore.getDataStore().getConnection((Transaction)transaction); + if (featureStore.getDataStore().getSQLDialect() instanceof NonSpatialDialect) { + if (featureStore.getPrimaryKey() == null || + featureStore.getPrimaryKey() instanceof org.geotools.jdbc.NullPrimaryKey || + featureStore.getPrimaryKey().getColumns().isEmpty()) + throw new SQLException("This FeatureTable has no PrimaryKey :: Non-Spatial DBMS Transaction needs PrimaryKey"); + for (FeatureId id : fID) { + String pkStringVlaue = id.getID().substring(id.getID().indexOf(".") + 1); + Double pkDoubleVlaue = Double.valueOf(Double.parseDouble(pkStringVlaue)); + onInsertIndexTable(cx, featureStore, pkDoubleVlaue, envelope); + } + } + if (!featureStore.getBounds().contains(envelope)) + onUpdateGeometryLayerTable(cx, featureStore); + transaction.commit(); + } catch (Exception e) { + transaction.rollback(); + throw new SQLException("Fail to insert Meta Table :: " + e); + } finally { + transaction.close(); + featureStore.getDataStore().closeSafe(cx); + } + } + + private static void onInsertIndexTable(Connection cx, JDBCFeatureStore featureStore, Double pkVlaue, Envelope envelope) throws Exception { + String gridKey = featureStore.getSchema().getTypeName(); + gridKey = String.valueOf(gridKey) + "_" + featureStore.getSchema().getGeometryDescriptor().getLocalName(); + gridKey = gridKey.toUpperCase(); + NonSpatialDialect dialect = (NonSpatialDialect)featureStore.getDataStore().getSQLDialect(); + Double gridSize = (Double)dialect.gridStore.get(gridKey); + String indexTableName = String.valueOf(gridKey) + "_INDEX"; + if (!ServerUtil.isNullString(featureStore.getDataStore().getDatabaseSchema())) + indexTableName = String.valueOf(featureStore.getDataStore().getDatabaseSchema().toUpperCase()) + + "." + indexTableName; + int sCol = (int)(envelope.getMinX() / gridSize.doubleValue()); + int eCol = (int)(envelope.getMinY() / gridSize.doubleValue()); + int sRow = (int)(envelope.getMaxX() / gridSize.doubleValue()); + int eRow = (int)(envelope.getMaxY() / gridSize.doubleValue()); + if (envelope.getMinX() < 0.0D) + sCol--; + if (envelope.getMinY() < 0.0D) + eCol--; + if (envelope.getMaxX() < 0.0D) + sRow--; + if (envelope.getMaxY() < 0.0D) + eRow--; + if (sCol == eCol) { + excuteInsertIndexTable(cx, indexTableName, pkVlaue.doubleValue(), sCol, sRow, envelope); + if (sRow != eRow) + excuteInsertIndexTable(cx, indexTableName, pkVlaue.doubleValue(), sCol, eRow, envelope); + } else { + excuteInsertIndexTable(cx, indexTableName, pkVlaue.doubleValue(), sCol, sRow, envelope); + excuteInsertIndexTable(cx, indexTableName, pkVlaue.doubleValue(), eCol, sRow, envelope); + if (sRow != eRow) { + excuteInsertIndexTable(cx, indexTableName, pkVlaue.doubleValue(), sCol, eRow, envelope); + excuteInsertIndexTable(cx, indexTableName, pkVlaue.doubleValue(), eCol, eRow, envelope); + } + } + } + + private static void excuteInsertIndexTable(Connection cx, String indexName, double id, double col, double row, Envelope envelope) throws Exception { + Statement stat = null; + try { + stat = cx.createStatement(); + stat.setFetchSize(1); + StringBuffer sql = new StringBuffer(); + sql.append("INSERT INTO "); + sql.append(indexName); + sql.append(" VALUES ("); + sql.append(id).append(", "); + sql.append(col).append(", "); + sql.append(row).append(", "); + sql.append(envelope.getMinX()).append(", "); + sql.append(envelope.getMaxX()).append(", "); + sql.append(envelope.getMinY()).append(", "); + sql.append(envelope.getMaxY()).append(" "); + sql.append(")"); + LogMngr.getInstance().logDebug("[DB]", "QUERY : " + sql.toString()); + stat.executeUpdate(sql.toString()); + } catch (Exception e) { + throw e; + } finally { + ConnMngr.getInstance().closeSafe(stat); + } + } + + public static FeatureId insertFeatureByLayer(String layerName, SimpleFeature feature, boolean useProvidedFid) throws Exception { + Layer layer; + try { + layer = ServerContext.getMap().getLayer(layerName); + if (!(layer instanceof FeatureLayer)) + throw new NullPointerException("Layer [" + layerName + "] is not FeatureLayer."); + } catch (Exception e) { + throw new NullPointerException("Layer [" + layerName + "] is not exist."); + } + FeatureLayer fLayer = (FeatureLayer)layer; + List resultFID = insertFeature(fLayer.getLayerType(), fLayer.getServerName(), fLayer.getSourceName(), feature, useProvidedFid); + fLayer.updateBBox(); + String newID = ((FeatureId)resultFID.get(0)).getID().replace(fLayer.getSourceName(), fLayer.getName()); + return (FeatureId)new FeatureIdImpl(newID); + } + + public static List insertFeatureCollectionByLayer(String layerName, SimpleFeatureCollection collection, boolean useProvidedFid) throws Exception { + Layer layer; + try { + layer = ServerContext.getMap().getLayer(layerName); + if (!(layer instanceof FeatureLayer)) + throw new NullPointerException("Layer [" + layerName + "] is not FeatureLayer."); + } catch (Exception e) { + throw new NullPointerException("Layer [" + layerName + "] is not exist."); + } + FeatureLayer fLayer = (FeatureLayer)layer; + List resultFID = insertFeatureCollection(fLayer.getLayerType(), fLayer.getServerName(), fLayer.getSourceName(), collection, useProvidedFid); + fLayer.updateBBox(); + for (FeatureId id : resultFID) { + String newID = id.getID().replace(fLayer.getSourceName(), fLayer.getName()); + FeatureIdImpl featureIdImpl = new FeatureIdImpl(newID); + } + return resultFID; + } + + public static int deleteFeatures(LayerFactory.LayerType layerType, String serverName, String tableName, Filter filter) throws Exception { + DefaultTransaction transaction = new DefaultTransaction("delete"); + try { + JDBCFeatureStore featureStore = O2DSMngr.getFeatureStore(layerType, serverName, tableName); + filter = QueryMngr.reFineFilter(featureStore.getSchema(), filter); + int count = featureStore.getCount(new Query(featureStore.getSchema().getTypeName(), filter)); + Set fids = new HashSet(); + if (featureStore.getDataStore().getSQLDialect() instanceof NonSpatialDialect) { + FeatureReader reader = featureStore.getReader(filter); + try { + while (reader.hasNext()) { + SimpleFeature feature = (SimpleFeature)reader.next(); + fids.add(feature.getIdentifier().getID()); + } + } finally { + reader.close(); + } + } + if (count == 0) + throw new NullPointerException("Delete target feature is empty."); + featureStore.setTransaction((Transaction)transaction); + featureStore.removeFeatures(filter); + transaction.commit(); + onDeleteMetaData(featureStore, fids); + LogMngr.getInstance().logInfo("[DB]", "Delete Success :: " + serverName + "/" + tableName + ">" + filter.toString()); + return count; + } catch (Exception e) { + transaction.rollback(); + LogMngr.getInstance().logError("[DB]", "Delete Fail :: " + e.getMessage()); + throw new SQLException("Delete Fail :: " + e.getMessage()); + } finally { + transaction.close(); + } + } + + private static void onDeleteMetaData(JDBCFeatureStore featureStore, Set fIDs) throws Exception { + DefaultTransaction transaction = new DefaultTransaction("delete meta"); + Connection cx = null; + try { + featureStore.setTransaction((Transaction)transaction); + cx = featureStore.getDataStore().getConnection((Transaction)transaction); + if (featureStore.getDataStore().getSQLDialect() instanceof NonSpatialDialect) { + if (featureStore.getPrimaryKey() == null || + featureStore.getPrimaryKey() instanceof org.geotools.jdbc.NullPrimaryKey || + featureStore.getPrimaryKey().getColumns().isEmpty()) + throw new SQLException("This FeatureTable has no PrimaryKey :: Non-Spatial DBMS Transaction needs PrimaryKey"); + onDeleteIndexTable(cx, featureStore, fIDs); + } + onUpdateGeometryLayerTable(cx, featureStore); + transaction.commit(); + } catch (Exception e) { + transaction.rollback(); + throw new SQLException("Fail to delete Meta Table :: " + e.toString()); + } finally { + transaction.close(); + featureStore.getDataStore().closeSafe(cx); + } + } + + private static void onDeleteIndexTable(Connection cx, JDBCFeatureStore featureStore, Set fIDs) throws Exception { + String indexTableName = featureStore.getSchema().getTypeName(); + indexTableName = String.valueOf(indexTableName) + "_" + featureStore.getSchema().getGeometryDescriptor().getLocalName(); + indexTableName = String.valueOf(indexTableName) + "_INDEX"; + indexTableName = indexTableName.toUpperCase(); + if (!ServerUtil.isNullString(featureStore.getDataStore().getDatabaseSchema())) + indexTableName = String.valueOf(featureStore.getDataStore().getDatabaseSchema().toUpperCase()) + + "." + indexTableName; + String pkColumn = ((PrimaryKeyColumn)featureStore.getPrimaryKey().getColumns().get(0)).getName().toUpperCase(); + Iterator iter = fIDs.iterator(); + while (iter.hasNext()) { + String fid = iter.next(); + String pkStringVlaue = fid.substring(fid.indexOf(".") + 1); + Double pkDoubleVlaue = Double.valueOf(Double.parseDouble(pkStringVlaue)); + excuteDeleteIndexTable(cx, indexTableName, pkColumn, pkDoubleVlaue.doubleValue()); + } + } + + private static void excuteDeleteIndexTable(Connection cx, String indexName, String columnName, double id) throws Exception { + Statement stat = null; + try { + stat = cx.createStatement(); + stat.setFetchSize(1); + StringBuffer sql = new StringBuffer(); + sql.append("DELETE FROM "); + sql.append(indexName); + sql.append(" WHERE "); + sql.append(columnName).append("="); + sql.append(id); + LogMngr.getInstance().logDebug("[DB]", "QUERY : " + sql.toString()); + stat.executeUpdate(sql.toString()); + } catch (Exception e) { + throw e; + } finally { + ConnMngr.getInstance().closeSafe(stat); + } + } + + public static int deleteFeaturesByLayer(String layerName, Filter filter) throws Exception { + Layer layer; + try { + layer = ServerContext.getMap().getLayer(layerName); + if (!(layer instanceof FeatureLayer)) + throw new NullPointerException("Layer [" + layerName + "] is not FeatureLayer."); + } catch (Exception e) { + throw new NullPointerException("Layer [" + layerName + "] is not exist."); + } + FeatureLayer fLayer = (FeatureLayer)layer; + int size = deleteFeatures(fLayer.getLayerType(), fLayer.getServerName(), fLayer.getSourceName(), filter); + fLayer.updateBBox(); + return size; + } + + public static int updateFeatures(LayerFactory.LayerType layerType, String serverName, String tableName, String[] names, Object[] values, Filter filter) throws Exception { + DefaultTransaction transaction = new DefaultTransaction("update"); + try { + JDBCFeatureStore featureStore = O2DSMngr.getFeatureStore(layerType, serverName, tableName); + filter = QueryMngr.reFineFilter(featureStore.getSchema(), filter); + refineUpdateFeature((ContentFeatureStore)featureStore, names, values); + int count = featureStore.getCount(new Query(featureStore.getSchema().getTypeName(), filter)); + Set fids = new HashSet(); + if (featureStore.getDataStore().getSQLDialect() instanceof NonSpatialDialect) { + FeatureReader reader = featureStore.getReader(filter); + try { + while (reader.hasNext()) { + SimpleFeature feature = (SimpleFeature)reader.next(); + fids.add(feature.getIdentifier().getID()); + } + } finally { + reader.close(); + } + } + if (count == 0) + throw new NullPointerException("Update target feature is empty."); + featureStore.setTransaction((Transaction)transaction); + featureStore.modifyFeatures(names, values, filter); + transaction.commit(); + String geomName = featureStore.getSchema().getGeometryDescriptor().getLocalName(); + for (int i = 0; i < names.length; i++) { + if (geomName.equalsIgnoreCase(names[i]) && + values[i] != null && + values[i] instanceof Geometry) + onUpdateMetaData(featureStore, fids, (Geometry)values[i]); + } + LogMngr.getInstance().logInfo("[DB]", "Update Success :: " + serverName + "/" + tableName + ">" + filter.toString()); + return count; + } catch (Exception e) { + transaction.rollback(); + LogMngr.getInstance().logInfo("[DB]", "Updata Fail :: " + e); + throw new SQLException("Updata Fail :: " + e); + } finally { + transaction.close(); + } + } + + private static void onUpdateMetaData(JDBCFeatureStore featureStore, Set fIDs, Geometry geometry) throws Exception { + DefaultTransaction transaction = new DefaultTransaction("update meta"); + Connection cx = null; + try { + featureStore.setTransaction((Transaction)transaction); + cx = featureStore.getDataStore().getConnection((Transaction)transaction); + if (featureStore.getDataStore().getSQLDialect() instanceof NonSpatialDialect) { + if (featureStore.getPrimaryKey() == null || + featureStore.getPrimaryKey() instanceof org.geotools.jdbc.NullPrimaryKey || + featureStore.getPrimaryKey().getColumns().isEmpty()) + throw new SQLException("This FeatureTable has no PrimaryKey :: Non-Spatial DBMS Transaction needs PrimaryKey"); + onUpdateIndexTable(cx, featureStore, fIDs, geometry.getEnvelopeInternal()); + } + if (!featureStore.getBounds().contains(geometry.getEnvelopeInternal())) + onUpdateGeometryLayerTable(cx, featureStore); + transaction.commit(); + } catch (Exception e) { + transaction.rollback(); + throw new SQLException("Fail to update Meta Table :: " + e); + } finally { + transaction.close(); + featureStore.getDataStore().closeSafe(cx); + } + } + + private static void onUpdateGeometryLayerTable(Connection cx, JDBCFeatureStore featureStore) throws Exception { + Statement stat = null; + try { + List envelopeList = null; + SQLDialect dialect = featureStore.getDataStore().getSQLDialect(); + if (dialect instanceof O2SqlDialect) + envelopeList = ((O2SqlDialect)dialect).getInternalBounds(featureStore.getDataStore().getDatabaseSchema(), featureStore.getSchema(), cx); + if (envelopeList == null || envelopeList.size() == 0) { + LogMngr.getInstance().logError("[DB]", + "Failed to update bounds of O2SERVER_GEOMETRY_LAYER."); + return; + } + ReferencedEnvelope internalEnvelope = envelopeList.get(0); + for (int i = 1; i < envelopeList.size(); i++) + internalEnvelope = GeometryMngr.mergeEnvelope(internalEnvelope, envelopeList.get(i)); + String metaTableName = "O2SERVER_GEOMETRY_LAYER"; + if (!ServerUtil.isNullString(featureStore.getDataStore().getDatabaseSchema())) + metaTableName = String.valueOf(featureStore.getDataStore().getDatabaseSchema().toUpperCase()) + + "." + metaTableName; + String tableName = featureStore.getSchema().getTypeName().toUpperCase(); + String colName = featureStore.getSchema().getGeometryDescriptor().getLocalName().toUpperCase(); + stat = cx.createStatement(); + stat.setFetchSize(1); + StringBuffer sql = new StringBuffer(); + sql.append("UPDATE ").append(metaTableName); + sql.append(" SET "); + sql.append("MIN_1D=").append(internalEnvelope.getMinX()).append(", "); + sql.append("MAX_1D=").append(internalEnvelope.getMaxX()).append(", "); + sql.append("MIN_2D=").append(internalEnvelope.getMinY()).append(", "); + sql.append("MAX_2D=").append(internalEnvelope.getMaxY()).append(" "); + sql.append(" WHERE "); + sql.append("TABLE_NAME='").append(tableName).append("' AND "); + sql.append("COLUMN_NAME='").append(colName).append("' "); + LogMngr.getInstance().logDebug("[DB]", "QUERY : " + sql.toString()); + stat.executeUpdate(sql.toString()); + } catch (Exception e) { + throw e; + } finally { + ConnMngr.getInstance().closeSafe(stat); + } + } + + private static void onUpdateIndexTable(Connection cx, JDBCFeatureStore featureStore, Set fIDs, Envelope envelope) throws Exception { + onDeleteIndexTable(cx, featureStore, fIDs); + for (String fid : fIDs) { + String pkStringVlaue = fid.substring(fid.indexOf(".") + 1); + Double pkVlaue = Double.valueOf(Double.parseDouble(pkStringVlaue)); + onInsertIndexTable(cx, featureStore, pkVlaue, envelope); + } + } + + private static void refineUpdateFeature(ContentFeatureStore featureStore, String[] names, Object[] values) throws Exception { + SimpleFeatureType featureType = featureStore.getSchema(); + for (int i = 0; i < names.length; i++) { + names[i] = names[i].toUpperCase(); + if (featureType.getDescriptor(names[i]) == null) + throw new Exception("Input Property [" + names[i] + "] is not exist."); + try { + if (values[i] != null && Geometry.class.isAssignableFrom(values[i].getClass())) { + Geometry tGeom = (Geometry)values[i]; + if (tGeom.getUserData() != null && tGeom.getUserData() instanceof CoordinateReferenceSystem) { + CoordinateReferenceSystem tCRS = (CoordinateReferenceSystem)tGeom.getUserData(); + if (!CRS.equalsIgnoreMetadata(featureType.getCoordinateReferenceSystem(), tCRS)) { + MathTransform transform = CRS.findMathTransform(tCRS, featureType.getCoordinateReferenceSystem(), true); + values[i] = JTS.transform(tGeom, transform); + } + } + if (featureStore instanceof JDBCFeatureStore) { + JDBCFeatureStore jdbcStore = (JDBCFeatureStore)featureStore; + if (jdbcStore.getDataStore().getSQLDialect() instanceof OracleDialect) { + OracleDialect oDialect = (OracleDialect)jdbcStore.getDataStore().getSQLDialect(); + Integer srid = oDialect.getDBSrid(featureType.getTypeName(), featureType.getGeometryDescriptor().getLocalName()); + if (srid != null && srid.intValue() == 0) { + oDialect.getClass(); + ((Geometry)values[i]).setUserData("OracleNullSrid"); + } + } + } + } + } catch (Exception e) { + throw new Exception("Fail to transform update geometry :: " + e); + } + } + } + + public static int updateFeaturesByLayer(String layerName, String[] names, Object[] values, Filter filter) throws Exception { + Layer layer; + try { + layer = ServerContext.getMap().getLayer(layerName); + if (!(layer instanceof FeatureLayer)) + throw new NullPointerException("Layer [" + layerName + "] is not FeatureLayer."); + } catch (Exception e) { + throw new NullPointerException("Layer [" + layerName + "] is not exist."); + } + FeatureLayer fLayer = (FeatureLayer)layer; + int size = updateFeatures(fLayer.getLayerType(), fLayer.getServerName(), fLayer.getSourceName(), names, values, filter); + fLayer.updateBBox(); + return size; + } + + private static SimpleFeatureType retypeFeatureType(SimpleFeatureType schema, String name) { + SimpleFeatureTypeBuilder tBuilder = new SimpleFeatureTypeBuilder(); + tBuilder.init(schema); + tBuilder.setName(name); + SimpleFeatureType newType = tBuilder.buildFeatureType(); + newType.getUserData().putAll(schema.getUserData()); + return newType; + } + + private static FeatureLock addFeatureLock(String lockID, int duration) throws Exception { + if (ServerUtil.isNullString(lockID)) + throw new NullPointerException("Lock ID is Null"); + lockID = lockID.trim().toUpperCase(); + Iterator> it = lockStore.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry entry = it.next(); + long l = Long.parseLong(((String)entry.getKey()).split(":")[1]); + if (l < System.currentTimeMillis()) + it.remove(); + } + long expireTime = System.currentTimeMillis() + (duration * 1000 * 60); + String authorization = String.valueOf(lockID) + ":" + expireTime; + FeatureLock lock = new FeatureLock(authorization, (duration * 1000 * 60)); + lockStore.put(lock.getAuthorization(), lock); + return lock; + } + + public static DefaultFeatureCollection lockFeature(LayerFactory.LayerType layerType, String serverName, String tableName, int duration, Filter filter) throws Exception { + JDBCFeatureStore featureStore = O2DSMngr.getFeatureStore(layerType, serverName, tableName); + filter = QueryMngr.reFineFilter(featureStore.getSchema(), filter); + FeatureLock lock = addFeatureLock(String.valueOf(serverName) + "." + tableName, duration); + DefaultTransaction defaultTransaction = new DefaultTransaction(); + defaultTransaction.addAuthorization(lock.getAuthorization()); + featureStore.setTransaction((Transaction)defaultTransaction); + DefaultFeatureCollection resultStore = new DefaultFeatureCollection(); + try { + LockingManager lockMngr = featureStore.getDataStore().getLockingManager(); + FeatureReader reader = featureStore.getReader(filter); + try { + while (reader.hasNext()) { + SimpleFeature feature = (SimpleFeature)reader.next(); + try { + lockMngr.lockFeatureID(featureStore.getSchema().getTypeName(), feature.getID(), (Transaction)defaultTransaction, lock); + feature.getUserData().put("LockFeatureId", lock.getAuthorization()); + feature.getUserData().put("LockFeatureResult", Boolean.valueOf(true)); + resultStore.add(feature); + } catch (FeatureLockException e) { + feature.getUserData().put("LockFeatureId", lock.getAuthorization()); + feature.getUserData().put("LockFeatureResult", Boolean.valueOf(false)); + resultStore.add(feature); + } + } + } finally { + reader.close(); + } + return resultStore; + } catch (Exception e) { + throw e; + } finally { + defaultTransaction.close(); + } + } + + public static DefaultFeatureCollection lockFeature(LayerFactory.LayerType layerType, String serverName, String tableName, int duration) throws Exception { + return lockFeature(layerType, serverName, tableName, duration, (Filter)Filter.INCLUDE); + } + + public static DefaultFeatureCollection lockFeatureByLayer(String layerName, int duration, Filter filter) throws Exception { + Layer layer; + try { + layer = ServerContext.getMap().getLayer(layerName); + if (!(layer instanceof FeatureLayer)) + throw new NullPointerException("Layer [" + layerName + "] is not FeatureLayer."); + } catch (Exception e) { + throw new NullPointerException("Layer [" + layerName + "] is not exist."); + } + FeatureLayer fLayer = (FeatureLayer)layer; + JDBCFeatureStore featureStore = O2DSMngr.getFeatureStore(fLayer.getLayerType(), fLayer.getServerName(), fLayer.getSourceName()); + filter = QueryMngr.reFineFilter(featureStore.getSchema(), filter); + FeatureLock lock = addFeatureLock(fLayer.getName(), duration); + DefaultTransaction defaultTransaction = new DefaultTransaction(); + defaultTransaction.addAuthorization(lock.getAuthorization()); + featureStore.setTransaction((Transaction)defaultTransaction); + DefaultFeatureCollection resultStore = new DefaultFeatureCollection(); + try { + SimpleFeatureType newType = retypeFeatureType(featureStore.getSchema(), layerName); + SimpleFeatureBuilder fBuilder = new SimpleFeatureBuilder(newType); + LockingManager lockMngr = featureStore.getDataStore().getLockingManager(); + FeatureReader reader = featureStore.getReader(filter); + try { + while (reader.hasNext()) { + String newID; + SimpleFeature feature = (SimpleFeature)reader.next(); + try { + lockMngr.lockFeatureID(featureStore.getSchema().getTypeName(), feature.getID(), (Transaction)defaultTransaction, lock); + feature.getUserData().put("LockFeatureId", lock.getAuthorization()); + feature.getUserData().put("LockFeatureResult", Boolean.valueOf(true)); + } catch (FeatureLockException e) { + feature.getUserData().put("LockFeatureId", lock.getAuthorization()); + feature.getUserData().put("LockFeatureResult", Boolean.valueOf(false)); + continue; + } finally { + String str = feature.getIdentifier().getID().replace(featureStore.getSchema().getTypeName(), layerName); + fBuilder.init(feature); + resultStore.add(fBuilder.buildFeature(str)); + } + } + } finally { + reader.close(); + } + return resultStore; + } catch (Exception e) { + throw e; + } finally { + defaultTransaction.close(); + } + } + + public static DefaultFeatureCollection lockFeatureByLayer(String layerName, int duration) throws Exception { + return lockFeatureByLayer(layerName, duration, (Filter)Filter.INCLUDE); + } + + public static DefaultFeatureCollection lockFeatureByLayer(List layerNameList, int duration, List filterList) throws Exception { + if (layerNameList == null || layerNameList.size() == 0) + throw new NullPointerException("LayerName List is NULL of empty."); + if (layerNameList.size() != filterList.size()) + throw new NullPointerException("Different size : Layers and Filters"); + List fLayerStore = new ArrayList(); + for (String layerName : layerNameList) { + try { + Layer layer = ServerContext.getMap().getLayer(layerName); + if (!(layer instanceof FeatureLayer)) + throw new NullPointerException("Layer [" + layerName + "] is not FeatureLayer."); + fLayerStore.add((FeatureLayer)layer); + } catch (Exception e) { + throw new NullPointerException("Layer [" + layerName + "] is not exist."); + } + } + String authStr = ""; + Iterator iter = fLayerStore.iterator(); + while (iter.hasNext()) { + FeatureLayer layer = iter.next(); + authStr = String.valueOf(authStr) + layer.getName(); + if (iter.hasNext()) + authStr = String.valueOf(authStr) + "+"; + } + DefaultFeatureCollection resultStore = new DefaultFeatureCollection(); + FeatureLock lock = addFeatureLock(authStr, duration); + for (int i = 0; i < fLayerStore.size(); i++) { + FeatureLayer layer = fLayerStore.get(i); + Filter filter = filterList.get(i); + JDBCFeatureStore featureStore = O2DSMngr.getFeatureStore(layer.getLayerType(), layer.getServerName(), layer.getSourceName()); + filter = QueryMngr.reFineFilter(featureStore.getSchema(), filter); + DefaultTransaction defaultTransaction = new DefaultTransaction(); + defaultTransaction.addAuthorization(lock.getAuthorization()); + featureStore.setTransaction((Transaction)defaultTransaction); + try { + SimpleFeatureType newType = retypeFeatureType(featureStore.getSchema(), layer.getName()); + SimpleFeatureBuilder fBuilder = new SimpleFeatureBuilder(newType); + LockingManager lockMngr = featureStore.getDataStore().getLockingManager(); + FeatureReader reader = featureStore.getReader(filter); + try { + while (reader.hasNext()) { + String newID; + SimpleFeature feature = (SimpleFeature)reader.next(); + try { + lockMngr.lockFeatureID(featureStore.getSchema().getTypeName(), feature.getID(), (Transaction)defaultTransaction, lock); + feature.getUserData().put("LockFeatureId", lock.getAuthorization()); + feature.getUserData().put("LockFeatureResult", Boolean.valueOf(true)); + } catch (FeatureLockException e) { + feature.getUserData().put("LockFeatureId", lock.getAuthorization()); + feature.getUserData().put("LockFeatureResult", Boolean.valueOf(false)); + continue; + } finally { + String str = feature.getIdentifier().getID().replace(featureStore.getSchema().getTypeName(), layer.getName()); + fBuilder.init(feature); + resultStore.add(fBuilder.buildFeature(str)); + } + } + } finally { + reader.close(); + } + } catch (Exception e) { + throw e; + } finally { + defaultTransaction.close(); + } + } + return resultStore; + } + + public static boolean unLockFeature(LayerFactory.LayerType layerType, String lockID, Filter filter) throws Exception { + FeatureLock lock = lockStore.get(lockID); + if (lock == null) + return false; + String tableNamesStr = lock.getAuthorization().split(":")[0]; + String[] tableNames = tableNamesStr.split("\\+"); + boolean isClear = true; + for (int i = 0; i < tableNames.length; i++) { + String[] tableCode = tableNames[i].split("\\."); + JDBCFeatureStore featureStore = O2DSMngr.getFeatureStore(layerType, tableCode[0], tableCode[1]); + filter = QueryMngr.reFineFilter(featureStore.getSchema(), filter); + DefaultTransaction defaultTransaction = new DefaultTransaction(); + featureStore.setTransaction((Transaction)defaultTransaction); + try { + defaultTransaction.addAuthorization(lock.getAuthorization()); + featureStore.unLockFeatures(filter); + if (featureStore.getDataStore().getLockingManager().exists(lock.getAuthorization())) + isClear = false; + } catch (Exception exception) { + + } finally { + defaultTransaction.close(); + } + } + if (isClear) + lockStore.remove(lock.getAuthorization()); + return true; + } + + public static boolean unLockFeatureByLayer(String lockID, Filter filter) throws Exception { + FeatureLock lock = lockStore.get(lockID); + if (lock == null) + return false; + String layerNamesStr = lock.getAuthorization().split(":")[0]; + String[] layerNames = layerNamesStr.split("\\+"); + boolean isClear = true; + for (int i = 0; i < layerNames.length; i++) { + Layer layer; + try { + layer = ServerContext.getMap().getLayer(layerNames[i]); + if (!(layer instanceof FeatureLayer)) + throw new NullPointerException("Layer [" + layerNames[i] + "] is not FeatureLayer."); + } catch (Exception e) { + throw new NullPointerException("Layer [" + layerNames[i] + "] is not exist."); + } + FeatureLayer fLayer = (FeatureLayer)layer; + JDBCFeatureStore featureStore = O2DSMngr.getFeatureStore(fLayer.getLayerType(), fLayer.getServerName(), fLayer.getSourceName()); + filter = QueryMngr.reFineFilter(featureStore.getSchema(), filter); + DefaultTransaction defaultTransaction = new DefaultTransaction(); + featureStore.setTransaction((Transaction)defaultTransaction); + try { + defaultTransaction.addAuthorization(lock.getAuthorization()); + featureStore.unLockFeatures(filter); + if (featureStore.getDataStore().getLockingManager().exists(lock.getAuthorization())) + isClear = false; + } catch (Exception exception) { + + } finally { + defaultTransaction.close(); + } + } + if (isClear) + lockStore.remove(lock.getAuthorization()); + return true; + } + + public static boolean unLockFeature(LayerFactory.LayerType layerType, String lockID) throws Exception { + return unLockFeature(layerType, lockID, (Filter)Filter.INCLUDE); + } + + public static boolean unLockFeatureByLayer(String lockID) throws Exception { + return unLockFeatureByLayer(lockID, (Filter)Filter.INCLUDE); + } +} diff --git a/src/main/java/com/geotwo/webserver/core/feature/GeometryMngr.java b/src/main/java/com/geotwo/webserver/core/feature/GeometryMngr.java new file mode 100644 index 0000000..2a16764 --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/feature/GeometryMngr.java @@ -0,0 +1,81 @@ +package com.geotwo.webserver.core.feature; + +import com.geotwo.webserver.core.map.LayerFactory; +import com.geotwo.webserver.core.map.layer.FeatureLayer; +import com.geotwo.webserver.core.map.layer.Layer; +import com.geotwo.webserver.core.vector.O2DSMngr; +import com.vividsolutions.jts.geom.Envelope; +import com.vividsolutions.jts.geom.LineString; +import com.vividsolutions.jts.geom.MultiLineString; +import com.vividsolutions.jts.geom.MultiPolygon; +import com.vividsolutions.jts.geom.Polygon; +import org.geotools.data.simple.SimpleFeatureSource; +import org.geotools.geometry.jts.ReferencedEnvelope; +import org.geotools.referencing.CRS; +import org.opengis.feature.simple.SimpleFeatureType; +import org.opengis.feature.type.GeometryDescriptor; +import org.opengis.referencing.FactoryException; +import org.opengis.referencing.crs.CoordinateReferenceSystem; +import org.opengis.referencing.operation.TransformException; + +public class GeometryMngr { + public enum GeomType { + POINT, LINE, POLYGON; + } + + public static GeomType getGeometryTypeByLayer(Layer layer) throws Exception { + if (layer instanceof FeatureLayer) { + FeatureLayer fLayer = (FeatureLayer)layer; + return getGeometryType(fLayer.getLayerType(), fLayer.getServerName(), fLayer.getSourceName()); + } + return null; + } + + public static GeomType getGeometryType(LayerFactory.LayerType layerType, String serverName, String tableName) throws Exception { + SimpleFeatureSource featureSource = O2DSMngr.getFeatureSource(layerType, serverName, tableName); + GeometryDescriptor geomDesc = ((SimpleFeatureType)featureSource.getSchema()).getGeometryDescriptor(); + Class clazz = geomDesc.getType().getBinding(); + if (Polygon.class.isAssignableFrom(clazz) || + MultiPolygon.class.isAssignableFrom(clazz)) + return GeomType.POLYGON; + if (LineString.class.isAssignableFrom(clazz) || + MultiLineString.class.isAssignableFrom(clazz)) + return GeomType.LINE; + return GeomType.POINT; + } + + public static String getGeometryColumnByLayer(Layer layer) throws Exception { + if (layer instanceof FeatureLayer) { + FeatureLayer fLayer = (FeatureLayer)layer; + return getGeometryColumn(fLayer.getLayerType(), fLayer.getServerName(), fLayer.getSourceName()); + } + return null; + } + + public static String getGeometryColumn(LayerFactory.LayerType layerType, String serverName, String tableName) throws Exception { + SimpleFeatureSource featureSource = O2DSMngr.getFeatureSource(layerType, serverName, tableName); + GeometryDescriptor geomDesc = ((SimpleFeatureType)featureSource.getSchema()).getGeometryDescriptor(); + return geomDesc.getLocalName(); + } + + public static ReferencedEnvelope mergeEnvelope(ReferencedEnvelope base, ReferencedEnvelope merge) throws TransformException, FactoryException { + if (base == null || base.isNull()) + return merge; + if (merge == null || merge.isNull()) + return base; + CoordinateReferenceSystem crsBase = base.getCoordinateReferenceSystem(); + CoordinateReferenceSystem crsMerge = merge.getCoordinateReferenceSystem(); + if (crsBase == null) { + merge.expandToInclude((Envelope)base); + return merge; + } + if (crsMerge == null) { + base.expandToInclude((Envelope)merge); + return base; + } + if (!CRS.equalsIgnoreMetadata(crsBase, crsMerge)) + merge = merge.transform(crsBase, true); + base.expandToInclude((Envelope)merge); + return base; + } +} diff --git a/src/main/java/com/geotwo/webserver/core/feature/InsertParams.java b/src/main/java/com/geotwo/webserver/core/feature/InsertParams.java new file mode 100644 index 0000000..111e967 --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/feature/InsertParams.java @@ -0,0 +1,17 @@ +package com.geotwo.webserver.core.feature; + +import java.util.ArrayList; +import org.opengis.filter.identity.FeatureId; + +class InsertParams { + public String sqlString; + + public Double maxValue; + + public ArrayList featureIDs = new ArrayList(); + + public InsertParams(String sql, Double max) { + this.sqlString = sql; + this.maxValue = max; + } +} diff --git a/src/main/java/com/geotwo/webserver/core/feature/O2FeatureCollection.java b/src/main/java/com/geotwo/webserver/core/feature/O2FeatureCollection.java new file mode 100644 index 0000000..101e208 --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/feature/O2FeatureCollection.java @@ -0,0 +1,175 @@ +package com.geotwo.webserver.core.feature; + +import java.io.IOException; +import java.util.Iterator; +import java.util.NoSuchElementException; +import org.geotools.data.DataUtilities; +import org.geotools.data.FeatureReader; +import org.geotools.data.collection.DelegateFeatureReader; +import org.geotools.data.simple.SimpleFeatureCollection; +import org.geotools.data.simple.SimpleFeatureIterator; +import org.geotools.feature.FeatureCollection; +import org.geotools.feature.FeatureIterator; +import org.geotools.feature.collection.DecoratingSimpleFeatureCollection; +import org.geotools.feature.simple.SimpleFeatureBuilder; +import org.geotools.feature.visitor.FeatureAttributeVisitor; +import org.geotools.filter.FilterAttributeExtractor; +import org.opengis.feature.Feature; +import org.opengis.feature.FeatureVisitor; +import org.opengis.feature.IllegalAttributeException; +import org.opengis.feature.Property; +import org.opengis.feature.simple.SimpleFeature; +import org.opengis.feature.simple.SimpleFeatureType; +import org.opengis.feature.type.AttributeDescriptor; +import org.opengis.feature.type.FeatureType; +import org.opengis.filter.expression.Expression; +import org.opengis.filter.expression.ExpressionVisitor; +import org.opengis.filter.expression.PropertyName; + +public class O2FeatureCollection extends DecoratingSimpleFeatureCollection { + SimpleFeatureType featureType; + + boolean isRetype = false; + + boolean isInitNullValue = false; + + public O2FeatureCollection(FeatureCollection delegate, SimpleFeatureType featureType) { + this(DataUtilities.simple(delegate), featureType); + } + + public O2FeatureCollection(SimpleFeatureCollection delegate, SimpleFeatureType fType) { + super(delegate); + if (fType == null) { + fType = (SimpleFeatureType)delegate.getSchema(); + } else { + this.isRetype = true; + } + this.featureType = fType; + } + + public SimpleFeatureType getSchema() { + return this.featureType; + } + + protected boolean canDelegate(FeatureVisitor visitor) { + if (visitor instanceof FeatureAttributeVisitor) { + FilterAttributeExtractor extractor = new FilterAttributeExtractor(this.featureType); + for (Expression e : ((FeatureAttributeVisitor)visitor).getExpressions()) + e.accept((ExpressionVisitor)extractor, null); + for (PropertyName pname : extractor.getPropertyNameSet()) { + AttributeDescriptor att = (AttributeDescriptor)pname.evaluate(this.featureType); + if (att == null) + return false; + } + return true; + } + return false; + } + + public FeatureReader reader() throws IOException { + return (FeatureReader)new DelegateFeatureReader((FeatureType)getSchema(), (FeatureIterator)features()); + } + + public boolean isRetype() { + return this.isRetype; + } + + public void setRetype(boolean bool) { + this.isRetype = bool; + } + + public boolean isInitNullValue() { + return this.isInitNullValue; + } + + public void setInitNullValue(boolean bool) { + this.isInitNullValue = bool; + } + + public SimpleFeatureIterator features() { + return new O2ReTypingFeatureIterator(this.delegate, getSchema(), isRetype(), isInitNullValue()); + } + + class O2ReTypingFeatureIterator implements SimpleFeatureIterator { + SimpleFeatureType source; + + AttributeDescriptor[] types; + + SimpleFeatureIterator delegate; + + SimpleFeatureType target; + + boolean retyping; + + boolean initNullValue = false; + + SimpleFeatureBuilder builder; + + public O2ReTypingFeatureIterator(SimpleFeatureCollection featuresource, SimpleFeatureType target, boolean retype, boolean nullValue) { + this.source = (SimpleFeatureType)featuresource.getSchema(); + this.target = target; + this.delegate = featuresource.features(); + this.retyping = retype; + this.initNullValue = nullValue; + this.builder = new SimpleFeatureBuilder(target); + } + + public SimpleFeatureIterator getDelegate() { + return this.delegate; + } + + public boolean hasNext() { + return this.delegate.hasNext(); + } + + public SimpleFeature next() { + SimpleFeature feature = (SimpleFeature)this.delegate.next(); + if (this.initNullValue) { + Iterator valueItr = feature.getValue().iterator(); + while (valueItr.hasNext()) { + Property property = valueItr.next(); + if (property.getValue() == null) + property.setValue(""); + } + } + if (!this.retyping) + return feature; + try { + String fid = feature.getID(); + this.types = O2FeatureCollection.this.typeAttributes(this.source, this.target); + for (int i = 0; i < this.types.length; i++) { + String xpath = this.types[i].getLocalName(); + this.builder.add(feature.getAttribute(xpath)); + } + fid = fid.replace(feature.getType().getTypeName(), this.target.getTypeName()); + return this.builder.buildFeature(fid); + } catch (IllegalAttributeException e) { + throw new RuntimeException(e); + } + } + + public void close() { + this.delegate.close(); + } + } + + protected AttributeDescriptor[] typeAttributes(SimpleFeatureType original, SimpleFeatureType target) { + if (target.equals(original)) + throw new IllegalArgumentException( + "FeatureReader allready produces contents with the correct schema"); + if (target.getAttributeCount() > original.getAttributeCount()) + throw new IllegalArgumentException( + "Unable to retype FeatureReader (origional does not cover requested type)"); + AttributeDescriptor[] types = new AttributeDescriptor[target.getAttributeCount()]; + for (int i = 0; i < target.getAttributeCount(); i++) { + AttributeDescriptor attrib = target.getDescriptor(i); + String xpath = attrib.getLocalName(); + types[i] = attrib; + if (!attrib.equals(original.getDescriptor(xpath))) + throw new IllegalArgumentException( + "Unable to retype FeatureReader (origional does not cover " + + xpath + ")"); + } + return types; + } +} diff --git a/src/main/java/com/geotwo/webserver/core/feature/QueryMngr.java b/src/main/java/com/geotwo/webserver/core/feature/QueryMngr.java new file mode 100644 index 0000000..ec7563d --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/feature/QueryMngr.java @@ -0,0 +1,187 @@ +package com.geotwo.webserver.core.feature; + +import com.vividsolutions.jts.geom.Envelope; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import org.geotools.data.DataUtilities; +import org.geotools.data.Query; +import org.geotools.factory.CommonFactoryFinder; +import org.geotools.factory.GeoTools; +import org.geotools.filter.FilterDOMParser; +import org.geotools.filter.spatial.ReprojectingFilterVisitor; +import org.geotools.filter.v1_1.OGCConfiguration; +import org.geotools.filter.visitor.DuplicatingFilterVisitor; +import org.geotools.filter.visitor.ExtractBoundsFilterVisitor; +import org.geotools.geometry.jts.ReferencedEnvelope; +import org.geotools.referencing.CRS; +import org.geotools.xml.Configuration; +import org.geotools.xml.Parser; +import org.opengis.feature.simple.SimpleFeatureType; +import org.opengis.feature.type.FeatureType; +import org.opengis.filter.Filter; +import org.opengis.filter.FilterFactory2; +import org.opengis.filter.FilterVisitor; +import org.opengis.filter.Id; +import org.opengis.filter.expression.Expression; +import org.opengis.filter.expression.PropertyName; +import org.opengis.filter.identity.Identifier; +import org.opengis.geometry.BoundingBox; +import org.opengis.referencing.crs.CoordinateReferenceSystem; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +public class QueryMngr { + private static final Configuration filterConfiguration = (Configuration)new OGCConfiguration(); + + public static final FilterFactory2 filterFactory = CommonFactoryFinder.getFilterFactory2(GeoTools.getDefaultHints()); + + public static Filter[] getFilters(String str) throws ParserConfigurationException, SAXException, IOException { + InputSource resource = new InputSource(); + resource.setCharacterStream(new StringReader(str)); + return parseFilters(resource); + } + + public static Filter[] getFilters(InputStream stream) throws ParserConfigurationException, SAXException, IOException { + InputSource resource = new InputSource(stream); + return parseFilters(resource); + } + + private static Filter[] parseFilters(InputSource resource) throws ParserConfigurationException, SAXException, IOException { + Filter[] filter = null; + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document dom = db.parse(resource); + NodeList nodes = dom.getElementsByTagNameNS("*", "Filter"); + filter = new Filter[nodes.getLength()]; + for (int j = 0; j < filter.length; j++) { + Element filterNode = (Element)nodes.item(j); + NodeList list = filterNode.getChildNodes(); + Node child = null; + for (int i = 0; i < list.getLength(); i++) { + child = list.item(i); + if (child != null && child.getNodeType() == 1) + filter[j] = FilterDOMParser.parseFilter(child); + } + } + return filter; + } + + public static Filter getFilter(String str) throws ParserConfigurationException, SAXException, IOException { + InputSource resource = new InputSource(); + resource.setCharacterStream(new StringReader(str)); + return parseFilter(resource); + } + + public static Filter getFilter(InputStream stream) throws ParserConfigurationException, SAXException, IOException { + InputSource resource = new InputSource(stream); + return parseFilter(resource); + } + + private static Filter parseFilter(InputSource resource) throws ParserConfigurationException, SAXException, IOException { + Parser parser = new Parser(filterConfiguration); + return (Filter)parser.parse(resource); + } + + private static Filter reProjectionFilter(SimpleFeatureType schema, Filter filter) { + ReprojectingFilterVisitor visitor = new ReprojectingFilterVisitor(filterFactory, (FeatureType)schema); + return (Filter)filter.accept((FilterVisitor)visitor, null); + } + + private static Filter upperCasePropertyNameFilter(Filter filter) { + DuplicatingFilterVisitor fVisitor = new DuplicatingFilterVisitor() { + public Object visit(PropertyName expression, Object extraData) { + String pName = expression.getPropertyName().toUpperCase(); + if (pName.contains(":")) + pName = pName.substring(pName.lastIndexOf(":") + 1); + return getFactory(extraData).property(pName, expression.getNamespaceContext()); + } + }; + return (Filter)filter.accept((FilterVisitor)fVisitor, null); + } + + private static Filter changeFIDFilter(final SimpleFeatureType schema, Filter filter) { + DuplicatingFilterVisitor fVisitor = new DuplicatingFilterVisitor() { + public Object visit(Id filter, Object extraData) { + Set fIDs = new HashSet(); + for (Identifier fid : filter.getIdentifiers()) { + String str = fid.toString(); + if (str.contains(".")) { + String pkStringVlaue = str.substring(str.indexOf(".") + 1); + str = String.valueOf(schema.getTypeName()) + "." + pkStringVlaue; + } + fIDs.add(getFactory(extraData).featureId(str)); + } + return getFactory(extraData).id(fIDs); + } + }; + return (Filter)filter.accept((FilterVisitor)fVisitor, null); + } + + private static Filter extractBBoxFilter(SimpleFeatureType schema, Filter filter) { + Envelope bounds = (Envelope)filter.accept((FilterVisitor)ExtractBoundsFilterVisitor.BOUNDS_VISITOR, null); + if (bounds == null || bounds.isNull()) + return null; + if (bounds.getMinX() == Double.NEGATIVE_INFINITY && + bounds.getMaxX() == Double.POSITIVE_INFINITY && + bounds.getMinY() == Double.NEGATIVE_INFINITY && + bounds.getMaxY() == Double.POSITIVE_INFINITY) + return null; + ReferencedEnvelope envelop = ReferencedEnvelope.reference(bounds); + String geomField = schema.getGeometryDescriptor().getLocalName(); + return (Filter)filterFactory.bbox((Expression)filterFactory.property(geomField), (BoundingBox)envelop); + } + + public static Query reFineQuery(SimpleFeatureType schema, Query query) { + query.setFilter(reFineFilter(schema, query.getFilter())); + Filter bboxFilter = extractBBoxFilter(schema, query.getFilter()); + if (bboxFilter != null) { + CoordinateReferenceSystem reprojCRS = query.getCoordinateSystemReproject(); + Query bboxQuery = new Query(schema.getTypeName(), bboxFilter); + bboxQuery.setHints(query.getHints()); + query = DataUtilities.mixQueries(query, bboxQuery, null); + if (reprojCRS != null && !CRS.equalsIgnoreMetadata(schema.getCoordinateReferenceSystem(), reprojCRS)) + query.setCoordinateSystemReproject(reprojCRS); + } + query.setTypeName(schema.getTypeName()); + if (query.getProperties() != null) { + ArrayList propertys = new ArrayList(); + String geom = schema.getGeometryDescriptor().getLocalName(); + boolean isContain = false; + byte b; + int i; + String[] arrayOfString; + for (i = (arrayOfString = query.getPropertyNames()).length, b = 0; b < i; ) { + String pName = arrayOfString[b]; + pName = pName.trim().toUpperCase(); + if (pName.equals(geom)) { + propertys.add(pName); + isContain = true; + } else if (schema.getDescriptor(pName) != null) { + propertys.add(pName); + } + b++; + } + query.setPropertyNames(propertys); + } + return query; + } + + public static Filter reFineFilter(SimpleFeatureType schema, Filter filter) { + Filter uppercaseFilter = upperCasePropertyNameFilter(filter); + Filter transformFilter = reProjectionFilter(schema, uppercaseFilter); + Filter changeFidFilter = changeFIDFilter(schema, transformFilter); + return changeFidFilter; + } +} diff --git a/src/main/java/com/geotwo/webserver/core/feature/RefindInsertFeatureCollection.java b/src/main/java/com/geotwo/webserver/core/feature/RefindInsertFeatureCollection.java new file mode 100644 index 0000000..1c9c796 --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/feature/RefindInsertFeatureCollection.java @@ -0,0 +1,167 @@ +package com.geotwo.webserver.core.feature; + +import com.geotwo.webserver.core.vector.jdbc.oracle.OracleDialect; +import com.vividsolutions.jts.geom.Geometry; +import java.io.IOException; +import java.util.NoSuchElementException; +import org.geotools.data.DataUtilities; +import org.geotools.data.FeatureReader; +import org.geotools.data.collection.DelegateFeatureReader; +import org.geotools.data.simple.SimpleFeatureCollection; +import org.geotools.data.simple.SimpleFeatureIterator; +import org.geotools.data.store.ContentFeatureStore; +import org.geotools.factory.Hints; +import org.geotools.feature.FeatureIterator; +import org.geotools.feature.collection.DecoratingSimpleFeatureCollection; +import org.geotools.feature.simple.SimpleFeatureBuilder; +import org.geotools.feature.visitor.FeatureAttributeVisitor; +import org.geotools.filter.FilterAttributeExtractor; +import org.geotools.geometry.jts.JTS; +import org.geotools.jdbc.JDBCFeatureStore; +import org.geotools.jdbc.PrimaryKeyColumn; +import org.geotools.referencing.CRS; +import org.opengis.feature.Feature; +import org.opengis.feature.FeatureVisitor; +import org.opengis.feature.simple.SimpleFeature; +import org.opengis.feature.simple.SimpleFeatureType; +import org.opengis.feature.type.AttributeDescriptor; +import org.opengis.feature.type.FeatureType; +import org.opengis.filter.expression.Expression; +import org.opengis.filter.expression.ExpressionVisitor; +import org.opengis.filter.expression.PropertyName; +import org.opengis.referencing.crs.CoordinateReferenceSystem; +import org.opengis.referencing.operation.MathTransform; + +public class RefindInsertFeatureCollection extends DecoratingSimpleFeatureCollection { + ContentFeatureStore featureStore; + + boolean useProvidedFid; + + public RefindInsertFeatureCollection(SimpleFeature delegate, ContentFeatureStore fStore, boolean providedFid) { + this(DataUtilities.collection(delegate), fStore, providedFid); + } + + public RefindInsertFeatureCollection(SimpleFeatureCollection delegate, ContentFeatureStore fStore, boolean providedFid) { + super(delegate); + this.featureStore = fStore; + this.useProvidedFid = providedFid; + } + + protected boolean canDelegate(FeatureVisitor visitor) { + if (visitor instanceof FeatureAttributeVisitor) { + FilterAttributeExtractor extractor = new FilterAttributeExtractor(getSchema()); + for (Expression e : ((FeatureAttributeVisitor)visitor).getExpressions()) + e.accept((ExpressionVisitor)extractor, null); + for (PropertyName pname : extractor.getPropertyNameSet()) { + AttributeDescriptor att = (AttributeDescriptor)pname.evaluate(getSchema()); + if (att == null) + return false; + } + return true; + } + return false; + } + + public ContentFeatureStore getFeatureStore() { + return this.featureStore; + } + + public FeatureReader reader() throws IOException { + return (FeatureReader)new DelegateFeatureReader((FeatureType)getSchema(), (FeatureIterator)features()); + } + + public SimpleFeatureIterator features() { + try { + return new O2RefindFeatureIterator(this.delegate.features(), getFeatureStore()); + } catch (IOException e) { + return null; + } + } + + class O2RefindFeatureIterator implements SimpleFeatureIterator { + SimpleFeatureIterator delegate; + + ContentFeatureStore featureStore; + + SimpleFeatureType featureType; + + SimpleFeatureBuilder builder; + + public O2RefindFeatureIterator(SimpleFeatureIterator delegate, ContentFeatureStore fStore) throws IOException { + this.delegate = delegate; + this.featureStore = fStore; + this.featureType = this.featureStore.getSchema(); + this.builder = new SimpleFeatureBuilder(this.featureType); + } + + public SimpleFeatureIterator getDelegate() { + return this.delegate; + } + + public boolean hasNext() { + return this.delegate.hasNext(); + } + + public SimpleFeature next() { + SimpleFeature feature = (SimpleFeature)this.delegate.next(); + String pkColumn = null; + if (this.featureStore instanceof JDBCFeatureStore) { + JDBCFeatureStore jdbcStore = (JDBCFeatureStore)this.featureStore; + if (jdbcStore.getPrimaryKey() != null && + jdbcStore.getPrimaryKey().getColumns().size() != 0) + pkColumn = ((PrimaryKeyColumn)jdbcStore.getPrimaryKey().getColumns().get(0)).getName(); + } + String newID = null; + for (AttributeDescriptor att : this.featureType.getAttributeDescriptors()) { + Object value = feature.getAttribute(att.getLocalName()); + if (value == null) + value = feature.getAttribute(att.getLocalName().toLowerCase()); + if (pkColumn != null && + pkColumn.equalsIgnoreCase(att.getLocalName()) && + value != null) + newID = value.toString(); + try { + if (value != null && Geometry.class.isAssignableFrom(value.getClass())) { + Geometry tGeom = (Geometry)value; + if (tGeom.getUserData() != null && + tGeom.getUserData() instanceof CoordinateReferenceSystem && + this.featureType.getCoordinateReferenceSystem() != null) { + CoordinateReferenceSystem tCRS = (CoordinateReferenceSystem)tGeom.getUserData(); + if (!CRS.equalsIgnoreMetadata(this.featureType.getCoordinateReferenceSystem(), tCRS)) { + MathTransform transform = CRS.findMathTransform(tCRS, this.featureType.getCoordinateReferenceSystem(), true); + value = JTS.transform(tGeom, transform); + } + } + if (this.featureStore instanceof JDBCFeatureStore) { + JDBCFeatureStore jdbcStore = (JDBCFeatureStore)this.featureStore; + if (jdbcStore.getDataStore().getSQLDialect() instanceof OracleDialect) { + OracleDialect oDialect = (OracleDialect)jdbcStore.getDataStore().getSQLDialect(); + Integer srid = oDialect.getDBSrid(this.featureType.getTypeName(), this.featureType.getGeometryDescriptor().getLocalName()); + if (srid != null && srid.intValue() == 0) { + oDialect.getClass(); + ((Geometry)value).setUserData("OracleNullSrid"); + } + } + } + } + } catch (Exception e) { + throw new RuntimeException("Fail to transform input geometry :: " + e); + } + this.builder.set(att.getLocalName(), value); + } + SimpleFeature newFeature = this.builder.buildFeature(newID); + if (feature.getUserData().size() > 0) + newFeature.getUserData().putAll(feature.getUserData()); + if (RefindInsertFeatureCollection.this.useProvidedFid && newID != null) { + newFeature.getUserData().put(Hints.USE_PROVIDED_FID, Boolean.valueOf(true)); + } else { + newFeature.getUserData().put(Hints.USE_PROVIDED_FID, Boolean.valueOf(false)); + } + return newFeature; + } + + public void close() { + this.delegate.close(); + } + } +} diff --git a/src/main/java/com/geotwo/webserver/core/init/ConnMngr.java b/src/main/java/com/geotwo/webserver/core/init/ConnMngr.java new file mode 100644 index 0000000..ae7b9a6 --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/init/ConnMngr.java @@ -0,0 +1,106 @@ +package com.geotwo.webserver.core.init; + +import com.geotwo.webserver.core.init.conn.ConnAltibase; +import com.geotwo.webserver.core.init.conn.ConnJDBC; +import com.geotwo.webserver.core.init.conn.ConnKairos; +import com.geotwo.webserver.core.init.conn.ConnMySQL; +import com.geotwo.webserver.core.init.conn.ConnOracle; +import com.geotwo.webserver.core.init.conn.ConnPostGIS; +import com.geotwo.webserver.core.init.conn.ConnTibero; +import com.geotwo.webserver.core.log.LogMngr; +import com.geotwo.webserver.core.vector.jdbc.O2DSFactory; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.HashMap; + +public class ConnMngr { + private static ConnMngr instance = null; + + private ConnJDBC connJDBC = null; + + public static ConnMngr getInstance() { + if (instance == null) + instance = new ConnMngr(); + return instance; + } + + public ConnJDBC getConnObj(String dbType) throws Exception { + if (dbType != null && dbType.toLowerCase().equals("altibase")) + return (ConnJDBC)new ConnAltibase(); + if (dbType != null && dbType.toLowerCase().equals("oracle")) + return (ConnJDBC)new ConnOracle(); + if (dbType != null && dbType.toLowerCase().equals("mysql")) + return (ConnJDBC)new ConnMySQL(); + if (dbType != null && dbType.toLowerCase().equals("postgis")) + return (ConnJDBC)new ConnPostGIS(); + if (dbType != null && dbType.toLowerCase().equals("tibero")) + return (ConnJDBC)new ConnTibero(); + if (dbType != null && dbType.toLowerCase().equals("kairos")) + return (ConnJDBC)new ConnKairos(); + LogMngr.getInstance().logError("[DB]", "Database type [" + dbType + "] is not support."); + throw new NullPointerException("Database type [" + dbType + "] is not support."); + } + + public ConnJDBC getConnObj(O2DSFactory.DBMSType dbType) throws Exception { + if (dbType != null && dbType == O2DSFactory.DBMSType.ALTIBASE) + return (ConnJDBC)new ConnAltibase(); + if (dbType != null && dbType == O2DSFactory.DBMSType.ORACLE) + return (ConnJDBC)new ConnOracle(); + if (dbType != null && dbType == O2DSFactory.DBMSType.MYSQL) + return (ConnJDBC)new ConnMySQL(); + if (dbType != null && dbType == O2DSFactory.DBMSType.POSTGIS) + return (ConnJDBC)new ConnPostGIS(); + if (dbType != null && dbType == O2DSFactory.DBMSType.TIBERO) + return (ConnJDBC)new ConnTibero(); + if (dbType != null && dbType == O2DSFactory.DBMSType.KAIROS) + return (ConnJDBC)new ConnKairos(); + LogMngr.getInstance().logError("[DB]", "Database type [" + dbType + "] is not support."); + throw new NullPointerException("Database type [" + dbType + "] is not support."); + } + + public Connection openConn() throws Exception { + HashMap map = ServerConfiguration.getInstance().getConfMap(); + String dbType = (String)map.get("conf.xml.map.dbtype"); + dbType = dbType.trim(); + if (dbType != null && dbType.toLowerCase().equals("altibase")) { + this.connJDBC = (ConnJDBC)new ConnAltibase(); + } else if (dbType != null && dbType.toLowerCase().equals("oracle")) { + this.connJDBC = (ConnJDBC)new ConnOracle(); + } else if (dbType != null && dbType.toLowerCase().equals("mysql")) { + this.connJDBC = (ConnJDBC)new ConnMySQL(); + } else if (dbType != null && dbType.toLowerCase().equals("postgis")) { + this.connJDBC = (ConnJDBC)new ConnPostGIS(); + } else if (dbType != null && dbType.toLowerCase().equals("tibero")) { + this.connJDBC = (ConnJDBC)new ConnTibero(); + } else if (dbType != null && dbType.toLowerCase().equals("kairos")) { + this.connJDBC = (ConnJDBC)new ConnKairos(); + } else { + LogMngr.getInstance().logError("[DB]", "Database type [" + dbType + "] is not support."); + throw new NullPointerException("Database type [" + dbType + "] is not support."); + } + return this.connJDBC.openConn(); + } + + public void closeConn() { + if (this.connJDBC != null) + this.connJDBC.closeConn(); + } + + public void closeSafe(Statement st) { + if (st == null) + return; + try { + st.close(); + } catch (SQLException sQLException) {} + } + + public void closeSafe(ResultSet rs) { + if (rs == null) + return; + try { + rs.close(); + } catch (SQLException sQLException) {} + } +} diff --git a/src/main/java/com/geotwo/webserver/core/init/ServerConfiguration.java b/src/main/java/com/geotwo/webserver/core/init/ServerConfiguration.java new file mode 100644 index 0000000..c376040 --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/init/ServerConfiguration.java @@ -0,0 +1,418 @@ +package com.geotwo.webserver.core.init; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.Statement; +import java.util.HashMap; +import java.util.HashSet; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import com.geotwo.webserver.core.ServerContext; +import com.geotwo.webserver.core.cache.LogCacheManager; +import com.geotwo.webserver.core.log.LogMngr; +import com.geotwo.webserver.core.render.RenderMngr; +import com.geotwo.webserver.core.util.ServerUtil; +import com.geotwo.webserver.core.vector.O2DSMngr; + +public class ServerConfiguration { + private static ServerConfiguration instance = null; + private HashMap confMap = null; + + private ServerConfiguration() { + } + + public static ServerConfiguration getInstance() { + if (instance == null) { + instance = new ServerConfiguration(); + } + return instance; + } + + public boolean startServer() { + try { + System.out.println("******************************"); + System.out.println("Load server_conf.xml"); + System.out.println("******************************"); + this.loadConf(); + System.out.println("Success :: Loading Configuration File :: WEB-INF/conf/server_conf.xml"); + } + catch (FileNotFoundException e) { + System.out.println("Fail :: Configuration Fil is not exist... :: " + e); + return false; + } + catch (ParserConfigurationException e) { + System.out.println("Fail :: parsing Configuration File... :: " + e); + return false; + } + catch (SAXException e) { + System.out.println("Fail :: parsing Configuration File... :: " + e); + return false; + } + catch (IOException e) { + System.out.println("Fail :: loading Configuration File... :: " + e); + return false; + } + catch (Exception e) { + System.out.println("Fail :: can't access Configuration File... :: " + e); + return false; + } + try { + System.out.println(""); + System.out.println("******************************"); + System.out.println("Init Logging Service"); + System.out.println("******************************"); + LogMngr.getInstance().initLog(this.confMap); + System.out.println("Success :: Starting Logging Service!!!"); + if (LogMngr.getInstance().getLogDirctory() != null) { + LogMngr.getInstance().logInfo("[CACHE]", "------------------------------"); + LogMngr.getInstance().logInfo("[CACHE]", "Init log cache service"); + LogMngr.getInstance().logInfo("[CACHE]", "------------------------------"); + LogMngr.getInstance().logInfo("[CACHE]", ""); + LogCacheManager.getInstance().start(this.confMap); + } + } + catch (Exception e) { + System.out.println("Fail :: Stop Logging Service..." + e.getMessage()); + } + LogMngr.getInstance().logInfo("[SERVER]", ""); + LogMngr.getInstance().logInfo("[SERVER]", "================================="); + LogMngr.getInstance().logInfo("[SERVER]", "Server loading... "); + LogMngr.getInstance().logInfo("[SERVER]", "================================="); + LogMngr.getInstance().logInfo("[SERVER]", ""); + LogMngr.getInstance().logInfo("[MAP]", "-------------------------------------------"); + LogMngr.getInstance().logInfo("[MAP]", "Initialize ServiceMap"); + LogMngr.getInstance().logInfo("[MAP]", "-------------------------------------------"); + try { + ServerContext.initMap((String)((String)this.confMap.get("conf.xml.map.servicemap")), (String)((String)this.confMap.get("conf.xml.map.namespace"))); + LogMngr.getInstance().logInfo("[MAP]", "Now use this ServiceMap :: [" + ServerContext.getMap().getName() + "]"); + LogMngr.getInstance().logInfo("[MAP]", "Now use this NameSpace :: [" + ServerContext.getMap().getNameSpace() + "]"); + LogMngr.getInstance().logInfo("[MAP]", "Now use this NameSpaceURI :: [" + ServerContext.getMap().getNameSpaceURI() + "]"); + } + catch (Exception e) { + LogMngr.getInstance().logError("[SERVER]", ""); + LogMngr.getInstance().logError("[SERVER]", "=========================================="); + LogMngr.getInstance().logError("[SERVER]", "Stop Server :: ServiceMap is not availiable. ::" + e.getMessage()); + LogMngr.getInstance().logError("[SERVER]", "=========================================="); + LogMngr.getInstance().logError("[SERVER]", ""); + this.stopServer(); + return false; + } + LogMngr.getInstance().logInfo("[MAP]", ""); + try { + ServerContext.initLayers(); + } + catch (Exception e) { + LogMngr.getInstance().logError("[SERVER]", ""); + LogMngr.getInstance().logError("[SERVER]", "=========================================="); + LogMngr.getInstance().logError("[SERVER]", "Stop Server :: Initializing Layer Fail ::" + e.getMessage()); + LogMngr.getInstance().logError("[SERVER]", "=========================================="); + LogMngr.getInstance().logError("[SERVER]", ""); + this.stopServer(); + return false; + } + LogMngr.getInstance().logInfo("[SERVER]", ""); + LogMngr.getInstance().logInfo("[SERVER]", "================================="); + LogMngr.getInstance().logInfo("[SERVER]", "Server Starting..."); + LogMngr.getInstance().logInfo("[SERVER]", "================================="); + LogMngr.getInstance().logInfo("[SERVER]", ""); + return true; + } + + public void stopServer() { + ServerContext.initOptions(); + O2DSMngr.disposeStores(); + ConnMngr connMngr = ConnMngr.getInstance(); + connMngr.closeConn(); + LogCacheManager.getInstance().stop(); + RenderMngr.disposeRenderingPool(); + } + + private synchronized void loadConf() throws Exception { + if (this.confMap == null) { + this.confMap = new HashMap(); + } else { + this.confMap.clear(); + } + ServerContext.initOptions(); + File confFile = new File(ServerContext.getConfFolder(), "/server_conf.xml"); + System.out.println("Configuration File Location :: " + confFile.getAbsolutePath()); + if (!confFile.exists()) { + throw new FileNotFoundException("Configuration File is not exist [" + confFile.getAbsolutePath() + "]"); + } + System.out.println("Now try parse Configuration File"); + SAXParserFactory factory = SAXParserFactory.newInstance(); + SAXParser parser = factory.newSAXParser(); + ConfParserHandler handler = new ConfParserHandler(); + parser.parse(confFile, (DefaultHandler)handler); + } + + public HashSet getMapList() throws Exception { + HashSet mapList = new HashSet(); + Connection connection = null; + Statement stmt = null; + ResultSet rs = null; + try { + try { + connection = ConnMngr.getInstance().openConn(); + stmt = connection.createStatement(); + String sql = "SELECT MAP_NAME FROM O2MAP_SERVICE_INFO"; + LogMngr.getInstance().logDebug("[MAP]", "Load MapList :: SQL > " + sql); + rs = stmt.executeQuery(sql); + if (rs != null) { + while (rs.next()) { + String mapName = rs.getString(1); + if (ServerUtil.isNullString((String)mapName)) { + LogMngr.getInstance().logDebug("[MAP]", "Skip this layer :: MAP_NAME is NULL"); + continue; + } + if (!mapList.add(mapName.trim().toUpperCase())) continue; + LogMngr.getInstance().logDebug("[MAP]", "Add MAP_NAME [" + mapList.size() + "/" + mapName.trim().toUpperCase() + "]"); + } + } + if (mapList.size() == 0) { + throw new Exception("Map Count is [0]"); + } + LogMngr.getInstance().logInfo("[MAP]", "Success to load MapList :: Map Count is [" + mapList.size() + "]"); + } + catch (Exception e) { + LogMngr.getInstance().logError("[MAP]", "Fail to load MapList :: " + e.getMessage()); + throw e; + } + } + catch (Throwable throwable) { + ConnMngr.getInstance().closeConn(); + ConnMngr.getInstance().closeSafe(stmt); + ConnMngr.getInstance().closeSafe(rs); + throw throwable; + } + ConnMngr.getInstance().closeConn(); + ConnMngr.getInstance().closeSafe(stmt); + ConnMngr.getInstance().closeSafe(rs); + return mapList; + } + + public HashMap getConfMap() { + return this.confMap; + } + + class ConfParserHandler + extends DefaultHandler { + boolean isServer = false; + boolean isMap = false; + boolean isDbtype = false; + boolean isHost = false; + boolean isPort = false; + boolean isDatabase = false; + boolean isUser = false; + boolean isPasswd = false; + boolean isServicemap = false; + boolean isOption = false; + boolean isNamespace = false; + boolean isUseNS = false; + boolean isDocIndent = false; + boolean isDefaultMaxFeatures = false; + boolean isEncryption = false; + boolean isLog = false; + boolean isLogDir = false; + boolean isLogLevel = false; + boolean isLogRequest = false; + boolean isLogCache = false; + boolean isLogCacheType = false; + boolean isLogCacheValue = false; + boolean isAdmin = false; + boolean isSecure_key = false; + boolean isStyle_key = false; + + ConfParserHandler() { + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + if (this.isServer) { + if (this.isMap) { + if (qName.equalsIgnoreCase("DBTYPE")) { + this.isDbtype = true; + } else if (qName.equalsIgnoreCase("HOST")) { + this.isHost = true; + } else if (qName.equalsIgnoreCase("PORT")) { + this.isPort = true; + } else if (qName.equalsIgnoreCase("DATABASE")) { + this.isDatabase = true; + } else if (qName.equalsIgnoreCase("USER")) { + this.isUser = true; + } else if (qName.equalsIgnoreCase("PASSWD")) { + this.isPasswd = true; + } else if (qName.equalsIgnoreCase("SERVICEMAP")) { + this.isServicemap = true; + } else if (qName.equalsIgnoreCase("OPTION")) { + this.isOption = true; + } else if (qName.equalsIgnoreCase("NAMESPACE")) { + this.isNamespace = true; + } else if (qName.equalsIgnoreCase("USENS")) { + this.isUseNS = true; + } else if (qName.equalsIgnoreCase("DOCINDENT")) { + this.isDocIndent = true; + } else if (qName.equalsIgnoreCase("DEFAULTMAXFEATURES")) { + this.isDefaultMaxFeatures = true; + } else if (qName.equalsIgnoreCase("ENCRYPTION")) { + this.isEncryption = true; + } + } else if (this.isLog) { + if (qName.equalsIgnoreCase("DIR")) { + this.isLogDir = true; + } else if (qName.equalsIgnoreCase("LEVEL")) { + this.isLogLevel = true; + } else if (qName.equalsIgnoreCase("REQUEST")) { + this.isLogRequest = true; + } else if (qName.equalsIgnoreCase("CACHE")) { + this.isLogCache = true; + } else if (qName.equalsIgnoreCase("TYPE")) { + this.isLogCacheType = true; + } else if (qName.equalsIgnoreCase("VALUE")) { + this.isLogCacheValue = true; + } + } else if (this.isAdmin) { + if (qName.equalsIgnoreCase("SECUREKEY")) { + this.isSecure_key = true; + } else if (qName.equalsIgnoreCase("STYLEKEY")) { + this.isStyle_key = true; + } + } + if (qName.equalsIgnoreCase("MAP")) { + this.isMap = true; + } else if (qName.equalsIgnoreCase("LOG")) { + this.isLog = true; + } else if (qName.equalsIgnoreCase("ADMIN")) { + this.isAdmin = true; + } + } + if (qName.equalsIgnoreCase("SERVER")) { + this.isServer = true; + } + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + if (this.isServer) { + if (this.isMap) { + if (qName.equalsIgnoreCase("DBTYPE")) { + this.isDbtype = false; + } else if (qName.equalsIgnoreCase("HOST")) { + this.isHost = false; + } else if (qName.equalsIgnoreCase("PORT")) { + this.isPort = false; + } else if (qName.equalsIgnoreCase("DATABASE")) { + this.isDatabase = false; + } else if (qName.equalsIgnoreCase("USER")) { + this.isUser = false; + } else if (qName.equalsIgnoreCase("PASSWD")) { + this.isPasswd = false; + } else if (qName.equalsIgnoreCase("SERVICEMAP")) { + this.isServicemap = false; + } else if (qName.equalsIgnoreCase("OPTION")) { + this.isOption = false; + } else if (qName.equalsIgnoreCase("NAMESPACE")) { + this.isNamespace = false; + } else if (qName.equalsIgnoreCase("USENS")) { + this.isUseNS = false; + } else if (qName.equalsIgnoreCase("DOCINDENT")) { + this.isDocIndent = false; + } else if (qName.equalsIgnoreCase("DEFAULTMAXFEATURES")) { + this.isDefaultMaxFeatures = false; + } else if (qName.equalsIgnoreCase("ENCRYPTION")) { + this.isEncryption = false; + } + } else if (this.isLog) { + if (qName.equalsIgnoreCase("DIR")) { + this.isLogDir = false; + } else if (qName.equalsIgnoreCase("LEVEL")) { + this.isLogLevel = false; + } else if (qName.equalsIgnoreCase("REQUEST")) { + this.isLogRequest = false; + } else if (qName.equalsIgnoreCase("CACHE")) { + this.isLogCache = false; + } else if (qName.equalsIgnoreCase("TYPE")) { + this.isLogCacheType = false; + } else if (qName.equalsIgnoreCase("VALUE")) { + this.isLogCacheValue = false; + } + } else if (this.isAdmin) { + if (qName.equalsIgnoreCase("SECUREKEY")) { + this.isSecure_key = false; + } else if (qName.equalsIgnoreCase("STYLEKEY")) { + this.isStyle_key = false; + } + } + if (qName.equalsIgnoreCase("MAP")) { + this.isMap = false; + } else if (qName.equalsIgnoreCase("LOG")) { + this.isLog = false; + } else if (qName.equalsIgnoreCase("ADMIN")) { + this.isAdmin = false; + } + } + if (qName.equalsIgnoreCase("SERVER")) { + this.isServer = false; + } + } + + @Override + public void characters(char[] ch, int start, int length) throws SAXException { + if (this.isServer) { + if (this.isMap) { + if (this.isDbtype) { + ServerConfiguration.this.confMap.put("conf.xml.map.dbtype", new String(ch, start, length)); + } else if (this.isHost) { + ServerConfiguration.this.confMap.put("conf.xml.map.host", new String(ch, start, length)); + } else if (this.isPort) { + ServerConfiguration.this.confMap.put("conf.xml.map.port", new String(ch, start, length)); + } else if (this.isDatabase) { + ServerConfiguration.this.confMap.put("conf.xml.map.database", new String(ch, start, length)); + } else if (this.isUser) { + ServerConfiguration.this.confMap.put("conf.xml.map.user", new String(ch, start, length)); + } else if (this.isPasswd) { + ServerConfiguration.this.confMap.put("conf.xml.map.passwd", new String(ch, start, length)); + } else if (this.isServicemap) { + ServerConfiguration.this.confMap.put("conf.xml.map.servicemap", new String(ch, start, length)); + } else if (this.isNamespace) { + ServerConfiguration.this.confMap.put("conf.xml.map.namespace", new String(ch, start, length)); + } else if (this.isUseNS) { + ServerConfiguration.this.confMap.put("conf.xml.map.usedefaultnsprefix", new String(ch, start, length)); + } else if (this.isDocIndent) { + ServerConfiguration.this.confMap.put("conf.xml.map.docindent", new String(ch, start, length)); + } else if (this.isDefaultMaxFeatures) { + ServerConfiguration.this.confMap.put("conf.xml.map.default.max.features", new String(ch, start, length)); + } else if (this.isEncryption) { + ServerConfiguration.this.confMap.put("conf.xml.map.encryption", new String(ch, start, length)); + } + } else if (this.isLog) { + if (this.isLogDir) { + ServerConfiguration.this.confMap.put("conf.xml.log.dir", new String(ch, start, length)); + } else if (this.isLogLevel) { + ServerConfiguration.this.confMap.put("conf.xml.log.level", new String(ch, start, length)); + } else if (this.isLogRequest) { + ServerConfiguration.this.confMap.put("conf.xml.log.request", new String(ch, start, length)); + } else if (this.isLogCacheType) { + ServerConfiguration.this.confMap.put("conf.xml.log.cache.type", new String(ch, start, length)); + } else if (this.isLogCacheValue) { + ServerConfiguration.this.confMap.put("conf.xml.log.cache.value", new String(ch, start, length)); + } + } else if (this.isAdmin) { + if (this.isSecure_key) { + ServerConfiguration.this.confMap.put("conf.xml.admin.secure.key", new String(ch, start, length)); + } else if (this.isStyle_key) { + ServerConfiguration.this.confMap.put("conf.xml.admin.style.key", new String(ch, start, length)); + } + } + } + } + } +} \ No newline at end of file diff --git a/src/main/java/com/geotwo/webserver/core/init/conn/ConnAltibase.java b/src/main/java/com/geotwo/webserver/core/init/conn/ConnAltibase.java new file mode 100644 index 0000000..de040b5 --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/init/conn/ConnAltibase.java @@ -0,0 +1,29 @@ +package com.geotwo.webserver.core.init.conn; + +import com.geotwo.webserver.core.init.conn.util.FieldSQL; +import com.geotwo.webserver.core.vector.jdbc.O2DSFactory; +import java.util.HashMap; + +public class ConnAltibase extends ConnJDBC { + public String getDriverClassName() { + return "Altibase.jdbc.driver.AltibaseDriver"; + } + + public String getJDBCUrl(String host, Integer port, String database) { + String sURL = "jdbc:Altibase://"; + sURL = String.valueOf(sURL) + host + ":" + port + "/" + database; + return sURL; + } + + public FieldSQL getFieldSQL() { + HashMap fields = new HashMap(); + fields.put(FieldSQL.FieldType.GEOMETRY, "GEOMETRY"); + fields.put(FieldSQL.FieldType.CHARACTER, "VARCHAR"); + fields.put(FieldSQL.FieldType.NUMERIC, "NUMERIC"); + fields.put(FieldSQL.FieldType.BOOLEAN, "SMALLINT"); + fields.put(FieldSQL.FieldType.DATE, "DATE"); + fields.put(FieldSQL.FieldType.BLOB, "BLOB"); + fields.put(FieldSQL.FieldType.UNKNOWN, "VARCHAR(100)"); + return new FieldSQL(O2DSFactory.DBMSType.ALTIBASE, fields, false); + } +} diff --git a/src/main/java/com/geotwo/webserver/core/init/conn/ConnJDBC.java b/src/main/java/com/geotwo/webserver/core/init/conn/ConnJDBC.java new file mode 100644 index 0000000..1c3f578 --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/init/conn/ConnJDBC.java @@ -0,0 +1,66 @@ +package com.geotwo.webserver.core.init.conn; + +import com.geotwo.webserver.core.init.ServerConfiguration; +import com.geotwo.webserver.core.init.conn.util.FieldSQL; +import com.geotwo.webserver.core.log.LogMngr; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.HashMap; + +public abstract class ConnJDBC { + protected Connection connection = null; + + public ConnJDBC() { + DriverManager.setLoginTimeout(5); + } + + public Connection openConn() throws Exception { + if (this.connection != null) + return this.connection; + HashMap map = ServerConfiguration.getInstance().getConfMap(); + String sURL = getJDBCUrl(); + String user = (String)map.get("conf.xml.map.user"); + String passwd = (String)map.get("conf.xml.map.passwd"); + try { + Class.forName(getDriverClassName()); + } catch (Exception e) { + LogMngr.getInstance().logError("[DB]", "Can't register JDBC Driver :: " + e.getMessage()); + throw new Exception("Can't register JDBC Driver :: " + e.getMessage()); + } + try { + LogMngr.getInstance().logDebug("[DB]", "Open Connection :: " + sURL + ", " + user + ", " + passwd); + this.connection = DriverManager.getConnection(sURL, user, passwd); + } catch (SQLException e) { + LogMngr.getInstance().logError("[DB]", "Open Connection Fail :: " + e.getMessage()); + throw new SQLException("Open Connection Fail :: " + e.getMessage()); + } + return this.connection; + } + + public void closeConn() { + if (this.connection != null) + try { + if (!this.connection.isClosed()) + this.connection.close(); + this.connection = null; + } catch (SQLException e) { + this.connection = null; + LogMngr.getInstance().logError("[DB]", "Close Connection Fail :: " + e.getMessage()); + } + } + + public String getJDBCUrl() throws Exception { + HashMap map = ServerConfiguration.getInstance().getConfMap(); + String host = (String)map.get("conf.xml.map.host"); + String port = (String)map.get("conf.xml.map.port"); + String database = (String)map.get("conf.xml.map.database"); + return getJDBCUrl(host, Integer.valueOf(port), database); + } + + public abstract String getDriverClassName(); + + public abstract String getJDBCUrl(String paramString1, Integer paramInteger, String paramString2); + + public abstract FieldSQL getFieldSQL(); +} diff --git a/src/main/java/com/geotwo/webserver/core/init/conn/ConnKairos.java b/src/main/java/com/geotwo/webserver/core/init/conn/ConnKairos.java new file mode 100644 index 0000000..1b6c0fd --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/init/conn/ConnKairos.java @@ -0,0 +1,28 @@ +package com.geotwo.webserver.core.init.conn; + +import com.geotwo.webserver.core.init.conn.util.FieldSQL; +import com.geotwo.webserver.core.vector.jdbc.O2DSFactory; +import java.util.HashMap; + +public class ConnKairos extends ConnJDBC { + public String getDriverClassName() { + return "kr.co.realtimetech.kairos.jdbc.kairosDriver"; + } + + public String getJDBCUrl(String host, Integer port, String database) { + String sURL = "jdbc:kairos://"; + sURL = String.valueOf(sURL) + host + ":" + port + "/" + database; + return sURL; + } + + public FieldSQL getFieldSQL() { + HashMap fields = new HashMap(); + fields.put(FieldSQL.FieldType.GEOMETRY, "GEOMETRY"); + fields.put(FieldSQL.FieldType.NUMERIC, "NUMERIC"); + fields.put(FieldSQL.FieldType.BOOLEAN, "TINYINT"); + fields.put(FieldSQL.FieldType.DATE, "DATE"); + fields.put(FieldSQL.FieldType.BLOB, "BLOB"); + fields.put(FieldSQL.FieldType.UNKNOWN, "VARCHAR(100)"); + return new FieldSQL(O2DSFactory.DBMSType.KAIROS, fields, false); + } +} diff --git a/src/main/java/com/geotwo/webserver/core/init/conn/ConnMySQL.java b/src/main/java/com/geotwo/webserver/core/init/conn/ConnMySQL.java new file mode 100644 index 0000000..8a46de6 --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/init/conn/ConnMySQL.java @@ -0,0 +1,29 @@ +package com.geotwo.webserver.core.init.conn; + +import com.geotwo.webserver.core.init.conn.util.FieldSQL; +import com.geotwo.webserver.core.vector.jdbc.O2DSFactory; +import java.util.HashMap; + +public class ConnMySQL extends ConnJDBC { + public String getDriverClassName() { + return "com.mysql.jdbc.Driver"; + } + + public String getJDBCUrl(String host, Integer port, String database) { + String sURL = "jdbc:mysql://"; + sURL = String.valueOf(sURL) + host + ":" + port + "/" + database; + return sURL; + } + + public FieldSQL getFieldSQL() { + HashMap fields = new HashMap(); + fields.put(FieldSQL.FieldType.GEOMETRY, "GEOMETRY"); + fields.put(FieldSQL.FieldType.CHARACTER, "VARCHAR"); + fields.put(FieldSQL.FieldType.NUMERIC, "NUMERIC"); + fields.put(FieldSQL.FieldType.BOOLEAN, "TINYINT"); + fields.put(FieldSQL.FieldType.DATE, "DATE"); + fields.put(FieldSQL.FieldType.BLOB, "BLOB"); + fields.put(FieldSQL.FieldType.UNKNOWN, "VARCHAR(100)"); + return new FieldSQL(O2DSFactory.DBMSType.MYSQL, fields, true); + } +} diff --git a/src/main/java/com/geotwo/webserver/core/init/conn/ConnOracle.java b/src/main/java/com/geotwo/webserver/core/init/conn/ConnOracle.java new file mode 100644 index 0000000..32921f8 --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/init/conn/ConnOracle.java @@ -0,0 +1,29 @@ +package com.geotwo.webserver.core.init.conn; + +import com.geotwo.webserver.core.init.conn.util.FieldSQL; +import com.geotwo.webserver.core.vector.jdbc.O2DSFactory; +import java.util.HashMap; + +public class ConnOracle extends ConnJDBC { + public String getDriverClassName() { + return "oracle.jdbc.driver.OracleDriver"; + } + + public String getJDBCUrl(String host, Integer port, String database) { + String sURL = "jdbc:oracle:thin:@"; + sURL = String.valueOf(sURL) + host + ":" + port + ":" + database; + return sURL; + } + + public FieldSQL getFieldSQL() { + HashMap fields = new HashMap(); + fields.put(FieldSQL.FieldType.GEOMETRY, "SDO_GEOMETRY"); + fields.put(FieldSQL.FieldType.CHARACTER, "VARCHAR2"); + fields.put(FieldSQL.FieldType.NUMERIC, "NUMBER"); + fields.put(FieldSQL.FieldType.BOOLEAN, "CHAR(1)"); + fields.put(FieldSQL.FieldType.DATE, "DATE"); + fields.put(FieldSQL.FieldType.BLOB, "BLOB"); + fields.put(FieldSQL.FieldType.UNKNOWN, "VARCHAR2(100)"); + return new FieldSQL(O2DSFactory.DBMSType.ORACLE, fields, false); + } +} diff --git a/src/main/java/com/geotwo/webserver/core/init/conn/ConnPostGIS.java b/src/main/java/com/geotwo/webserver/core/init/conn/ConnPostGIS.java new file mode 100644 index 0000000..9d97809 --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/init/conn/ConnPostGIS.java @@ -0,0 +1,29 @@ +package com.geotwo.webserver.core.init.conn; + +import com.geotwo.webserver.core.init.conn.util.FieldSQL; +import com.geotwo.webserver.core.vector.jdbc.O2DSFactory; +import java.util.HashMap; + +public class ConnPostGIS extends ConnJDBC { + public String getDriverClassName() { + return "org.postgresql.Driver"; + } + + public String getJDBCUrl(String host, Integer port, String database) { + String sURL = "jdbc:postgresql://"; + sURL = String.valueOf(sURL) + host + ":" + port + "/" + database; + return sURL; + } + + public FieldSQL getFieldSQL() { + HashMap fields = new HashMap(); + fields.put(FieldSQL.FieldType.GEOMETRY, "GEOMETRY"); + fields.put(FieldSQL.FieldType.CHARACTER, "VARCHAR"); + fields.put(FieldSQL.FieldType.NUMERIC, "NUMERIC"); + fields.put(FieldSQL.FieldType.BOOLEAN, "BOOLEAN"); + fields.put(FieldSQL.FieldType.DATE, "DATE"); + fields.put(FieldSQL.FieldType.BLOB, "BYTEA"); + fields.put(FieldSQL.FieldType.UNKNOWN, "VARCHAR(100)"); + return new FieldSQL(O2DSFactory.DBMSType.POSTGIS, fields, true); + } +} diff --git a/src/main/java/com/geotwo/webserver/core/init/conn/ConnTibero.java b/src/main/java/com/geotwo/webserver/core/init/conn/ConnTibero.java new file mode 100644 index 0000000..e073ebd --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/init/conn/ConnTibero.java @@ -0,0 +1,29 @@ +package com.geotwo.webserver.core.init.conn; + +import com.geotwo.webserver.core.init.conn.util.FieldSQL; +import com.geotwo.webserver.core.vector.jdbc.O2DSFactory; +import java.util.HashMap; + +public class ConnTibero extends ConnJDBC { + public String getDriverClassName() { + return "com.tmax.tibero.jdbc.TbDriver"; + } + + public String getJDBCUrl(String host, Integer port, String database) { + String sURL = "jdbc:tibero:thin:@"; + sURL = String.valueOf(sURL) + host + ":" + port + ":" + database; + return sURL; + } + + public FieldSQL getFieldSQL() { + HashMap fields = new HashMap(); + fields.put(FieldSQL.FieldType.GEOMETRY, "GEOMETRY"); + fields.put(FieldSQL.FieldType.CHARACTER, "VARCHAR"); + fields.put(FieldSQL.FieldType.NUMERIC, "NUMBER"); + fields.put(FieldSQL.FieldType.BOOLEAN, "CHAR(1)"); + fields.put(FieldSQL.FieldType.DATE, "DATE"); + fields.put(FieldSQL.FieldType.BLOB, "BLOB"); + fields.put(FieldSQL.FieldType.UNKNOWN, "VARCHAR(100)"); + return new FieldSQL(O2DSFactory.DBMSType.TIBERO, fields, true); + } +} diff --git a/src/main/java/com/geotwo/webserver/core/init/conn/util/FieldInfo.java b/src/main/java/com/geotwo/webserver/core/init/conn/util/FieldInfo.java new file mode 100644 index 0000000..e565f38 --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/init/conn/util/FieldInfo.java @@ -0,0 +1,66 @@ +package com.geotwo.webserver.core.init.conn.util; + +public class FieldInfo { + private FieldSQL.FieldType type; + + private String name; + + private Integer precision; + + private Integer scale; + + private boolean primaryKey; + + private boolean notNull; + + public FieldInfo(String name, FieldSQL.FieldType type, Integer precision, Integer scale, boolean primaryKey, boolean notNull) { + this.type = type; + this.name = name.toUpperCase(); + this.precision = precision; + this.scale = scale; + this.primaryKey = primaryKey; + this.notNull = notNull; + } + + public FieldInfo(String name, FieldSQL.FieldType type, Integer precision, boolean primaryKey, boolean notNull) { + this.type = type; + this.name = name.toUpperCase(); + this.precision = precision; + this.scale = null; + this.primaryKey = primaryKey; + this.notNull = notNull; + } + + public FieldInfo(String name, FieldSQL.FieldType type, boolean primaryKey, boolean notNull) { + this.type = type; + this.name = name.toUpperCase(); + this.precision = null; + this.scale = null; + this.primaryKey = primaryKey; + this.notNull = notNull; + } + + public boolean isNotNull() { + return this.notNull; + } + + public boolean isPrimaryKey() { + return this.primaryKey; + } + + public String getName() { + return this.name; + } + + public FieldSQL.FieldType getType() { + return this.type; + } + + public Integer getScale() { + return this.scale; + } + + public Integer getPrecision() { + return this.precision; + } +} diff --git a/src/main/java/com/geotwo/webserver/core/init/conn/util/FieldSQL.java b/src/main/java/com/geotwo/webserver/core/init/conn/util/FieldSQL.java new file mode 100644 index 0000000..9aab325 --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/init/conn/util/FieldSQL.java @@ -0,0 +1,127 @@ +package com.geotwo.webserver.core.init.conn.util; + +import com.geotwo.webserver.core.log.LogMngr; +import com.geotwo.webserver.core.vector.jdbc.O2DSFactory; +import com.vividsolutions.jts.geom.Geometry; +import java.sql.SQLException; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +public class FieldSQL { + private final O2DSFactory.DBMSType dbType; + + private final Map dbFields; + + private final boolean isUnsignedScale; + + public enum FieldType { + GEOMETRY("GEOMETRY", new Class[] { Geometry.class, Geometry.class }), + CHARACTER("VARCHAR", new Class[] { String.class }), + NUMERIC("NUMBER", new Class[] { Short.class, Integer.class, Long.class, Float.class, Double.class }), + BOOLEAN("CHAR(1)", new Class[] { Boolean.class }), + DATE("DATE", new Class[] { Date.class }), + BLOB("BLOB", new Class[] { Byte[].class }), + UNKNOWN("VARCHAR", new Class[] { Object.class }); + + private final Class[] fieldTypes; + + private final String fieldSql; + + FieldType(String sql, Class... types) { + this.fieldSql = sql; + this.fieldTypes = types; + } + } + + public FieldSQL(O2DSFactory.DBMSType dbmsType, HashMap fields, boolean unsignedScale) { + this.dbType = dbmsType; + this.dbFields = Collections.unmodifiableMap(fields); + this.isUnsignedScale = unsignedScale; + } + + public O2DSFactory.DBMSType getDBType() { + return this.dbType; + } + + public String getGeomFieldType(Class geom, String srid) throws Exception { + String sql = this.dbFields.get(FieldType.GEOMETRY); + if (sql == null) + sql = FieldType.GEOMETRY.fieldSql; + return sql; + } + + public String getFieldType(Class clazz, int precision, int scale) throws Exception { + FieldType type = FieldType.UNKNOWN; + byte b; + int i; + FieldType[] arrayOfFieldType; + for (i = (arrayOfFieldType = FieldType.values()).length, b = 0; b < i; ) { + FieldType value = arrayOfFieldType[b]; + byte b1; + int j; + Class[] arrayOfClass; + for (j = (arrayOfClass = value.fieldTypes).length, b1 = 0; b1 < j; ) { + Class cls = arrayOfClass[b1]; + if (cls.isAssignableFrom(clazz)) + return getFieldType(value, precision, scale); + b1++; + } + b++; + } + return getFieldType(type, precision, scale); + } + + public String getFieldType(FieldType fType, int precision, int scale) throws Exception { + String sql = this.dbFields.get(fType); + if (sql == null) + sql = fType.fieldSql; + if (fType == FieldType.GEOMETRY || + fType == FieldType.BOOLEAN || + fType == FieldType.DATE || + fType == FieldType.BLOB || + fType == FieldType.UNKNOWN) + return sql; + if (precision < 0) { + LogMngr.getInstance().logError("[DB]", + "getFieldType :: precision is < 0 for " + fType); + throw new SQLException("getFieldType :: precision is < 0 for " + fType); + } + if (precision == 0 && scale == 0) { + LogMngr.getInstance().logError("[DB]", + "getFieldType :: precision and scale is 0 for " + fType); + throw new SQLException("getFieldType :: precision and scale is 0 for " + fType); + } + if (scale < 0) { + if (this.isUnsignedScale) { + LogMngr.getInstance().logError("[DB]", + "getFieldType :: scale is must use unsigned value for " + fType); + throw new SQLException("getFieldType :: scale is must use unsigned value for " + fType); + } + if (precision + scale <= 0) { + LogMngr.getInstance().logError("[DB]", + "getFieldType :: scale is over real length (" + precision + ") for " + fType); + throw new SQLException("getFieldType :: scale is over real length (" + precision + ") for " + fType); + } + } else if (precision - scale < 0) { + LogMngr.getInstance().logError("[DB]", + "getFieldType :: scale is over real length (" + precision + ") for " + fType); + throw new SQLException("getFieldType :: scale is over real length (" + precision + ") for " + fType); + } + StringBuffer sb = new StringBuffer(sql); + if (fType == FieldType.CHARACTER) { + if (precision == 0) { + LogMngr.getInstance().logError("[DB]", + "getFieldType :: precision is 0 for " + fType); + throw new SQLException("getFieldType :: precision is 0 for " + fType); + } + sb.append("(").append(precision).append(")"); + } else { + sb.append("("); + sb.append(precision).append(",").append(scale); + sb.append(")"); + } + return sb.toString(); + } +} diff --git a/src/main/java/com/geotwo/webserver/core/log/LogMngr.java b/src/main/java/com/geotwo/webserver/core/log/LogMngr.java new file mode 100644 index 0000000..869adba --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/log/LogMngr.java @@ -0,0 +1,219 @@ +package com.geotwo.webserver.core.log; + +import com.geotwo.webserver.core.util.ServerUtil; +import java.io.File; +import java.util.HashMap; +import java.util.Properties; +import org.apache.log4j.Level; +import org.apache.log4j.Logger; +import org.apache.log4j.PropertyConfigurator; + +public class LogMngr { + public static final String LOG_TYPE_CONFIG = "[CONFIG]"; + + public static final String LOG_TYPE_LICENSE = "[LICENSE]"; + + public static final String LOG_TYPE_DB = "[DB]"; + + public static final String LOG_TYPE_SERVER = "[SERVER]"; + + public static final String LOG_TYPE_MAP = "[MAP]"; + + public static final String LOG_TYPE_LAYER = "[LAYER]"; + + public static final String LOG_TYPE_JDBC = "[JDBC]"; + + public static final String LOG_TYPE_SHP = "[SHAPE]"; + + public static final String LOG_TYPE_GML = "[GML]"; + + public static final String LOG_TYPE_GWAVE = "[GWAVE]"; + + public static final String LOG_TYPE_WMTS = "[WMTS]"; + + public static final String LOG_TYPE_TMS = "[TMS]"; + + public static final String LOG_TYPE_O2WPS = "[O2WPS]"; + + public static final String LOG_TYPE_IMGCACHE = "[IMGCACHE]"; + + public static final String LOG_TYPE_O2IMG = "[O2IMG]"; + + public static final String LOG_TYPE_O2DEM = "[O2DEM]"; + + public static final String LOG_TYPE_O2INFO = "[O2INFO]"; + + public static final String LOG_TYPE_O2INDEX = "[O2INDEX]"; + + public static final String LOG_TYPE_SERVICE = "[SERVICE]"; + + public static final String LOG_TYPE_REQUEST = "[REQUEST]"; + + public static final String LOG_TYPE_RESPONSE = "[RESPONSE]"; + + public static final String LOG_TYPE_FILE = "[FILE]"; + + public static final String LOG_TYPE_CACHE = "[CACHE]"; + + public static final String LOG_TYPE_FEATURE = "[FEATURE]"; + + public static final String LOG_TYPE_RENDER = "[RENDER]"; + + public static final String LOG_TYPE_STYLE = "[STYLE]"; + + public static final String LOG_TYPE_CRS = "[CRS]"; + + private static LogMngr instance = null; + + private File logDir = null; + + private Level logLevel = null; + + private Level reqLevel = null; + + private Logger logger = null; + + private Logger loggerRequest = null; + + private LogMngr() { + initLog(null); + } + + public static LogMngr getInstance() { + if (instance == null) + instance = new LogMngr(); + return instance; + } + + public void initLog(HashMap map) { + this.logDir = null; + if (map == null) { + System.out.println("*********************************"); + System.out.println("Init LogMngr"); + System.out.println("*********************************"); + map = new HashMap(); + } else { + System.out.println("*********************************"); + System.out.println("Setup logging option for LogMngr"); + System.out.println("*********************************"); + } + String lValue = (String)map.get("conf.xml.log.level"); + if (ServerUtil.isNullString(lValue)) { + this.logLevel = Level.INFO; + System.out.println("- Log level value is null. Setup Logging basic [IFNO] level."); + } else { + lValue = lValue.trim().toUpperCase(); + if (lValue.equalsIgnoreCase("DEBUG")) { + this.logLevel = Level.DEBUG; + System.out.println("- Now Logging DEBUG level."); + } else if (lValue.equalsIgnoreCase("INFO")) { + this.logLevel = Level.INFO; + System.out.println("- Now Logging INFO level."); + } else if (lValue.equalsIgnoreCase("ERROR")) { + this.logLevel = Level.ERROR; + System.out.println("- Now Logging ERROR level."); + } else if (lValue.equalsIgnoreCase("FATAL")) { + this.logLevel = Level.FATAL; + System.out.println("- Now Logging FATAL level."); + } else { + this.logLevel = Level.INFO; + System.out.println("- Now Logging basic [IFNO] level."); + } + } + String rValue = (String)map.get("conf.xml.log.request"); + if (ServerUtil.getBooleanValue(rValue)) { + this.reqLevel = Level.INFO; + System.out.println("- Request log level value is TRUE."); + } else { + this.reqLevel = Level.ERROR; + System.out.println("- Request log level value is FALSE."); + } + String dValue = (String)map.get("conf.xml.log.dir"); + if (ServerUtil.isNullString(dValue)) { + this.logDir = null; + System.out.println("- Log file location[Directory name] is null. Now use only console logging."); + } else { + this.logDir = new File(dValue.trim()); + if (this.logDir.exists()) { + if (this.logDir.isDirectory()) { + this.logDir.setExecutable(true, false); + this.logDir.setReadable(true); + this.logDir.setWritable(true); + System.out.println("- Log file location[" + this.logDir.getAbsolutePath() + "] is activate."); + } else { + System.out.println("- Log file location[" + this.logDir.getAbsolutePath() + "] is not Directory. Now use only console logging."); + this.logDir = null; + } + } else if (this.logDir.mkdirs()) { + this.logDir.setExecutable(true, false); + this.logDir.setReadable(true); + this.logDir.setWritable(true); + System.out.println("- Log file location[" + this.logDir.getAbsolutePath() + "] is activate."); + } else { + System.out.println("- Log file location[" + this.logDir.getAbsolutePath() + "] is not available. Now use only console logging."); + this.logDir = null; + } + } + initLogger(); + } + + private void initLogger() { + Properties prop = new Properties(); + prop.setProperty("log4j.rootLogger", "OFF"); + prop.setProperty("log4j.logger.o2map.log", "INFO,stdout"); + prop.setProperty("log4j.logger.o2map.request", "INFO,stdout"); + prop.setProperty("log4j.appender.stdout", "org.apache.log4j.ConsoleAppender"); + prop.setProperty("log4j.appender.stdout.layout", "org.apache.log4j.PatternLayout"); + prop.setProperty("log4j.appender.stdout.layout.ConversionPattern", "%d{MMM dd HH:mm:ss} [%c{1}] > %p - %m%n"); + if (this.logDir != null) { + prop.setProperty("log4j.appender.o2log", "org.apache.log4j.DailyRollingFileAppender"); + prop.setProperty("log4j.appender.o2log.File", String.valueOf(this.logDir.getAbsolutePath()) + "/" + "o2map.log"); + prop.setProperty("log4j.appender.o2log.Append", "true"); + prop.setProperty("log4j.appender.o2log.DatePattern", "'.'yyyy-MM-dd-HH"); + prop.setProperty("log4j.appender.o2log.layout", "org.apache.log4j.PatternLayout"); + prop.setProperty("log4j.appender.o2log.layout.ConversionPattern", "%d{MMM dd HH:mm:ss} > %p - %m%n"); + prop.setProperty("log4j.appender.request", "org.apache.log4j.DailyRollingFileAppender"); + prop.setProperty("log4j.appender.request.File", String.valueOf(this.logDir.getAbsolutePath()) + "/" + "o2map_request.log"); + prop.setProperty("log4j.appender.request.Append", "true"); + prop.setProperty("log4j.appender.request.DatePattern", "'.'yyyy-MM-dd-HH"); + prop.setProperty("log4j.appender.request.layout", "org.apache.log4j.PatternLayout"); + prop.setProperty("log4j.appender.request.layout.ConversionPattern", "%d{MMM dd HH:mm:ss} > %p - %m%n"); + prop.setProperty("log4j.logger.o2map.log", "INFO,stdout,o2log"); + if (this.reqLevel == Level.INFO) + prop.setProperty("log4j.logger.o2map.request", "INFO,stdout,request"); + } + PropertyConfigurator.configure(prop); + this.logger = Logger.getLogger("o2map.log"); + this.loggerRequest = Logger.getLogger("o2map.request"); + this.logger.setLevel(this.logLevel); + this.loggerRequest.setLevel(this.reqLevel); + } + + public void reqInfo(String logType, String message) { + this.loggerRequest.info(String.valueOf(logType) + " " + message); + } + + public void logDebug(String logType, String message) { + this.logger.debug(String.valueOf(logType) + " " + message); + } + + public void logInfo(String logType, String message) { + this.logger.info(String.valueOf(logType) + " " + message); + } + + public void logWarn(String logType, String message) { + this.logger.warn(String.valueOf(logType) + " " + message); + } + + public void logError(String logType, String message) { + this.logger.error(String.valueOf(logType) + " " + message); + } + + public void logFatal(String logType, String message) { + this.logger.fatal(String.valueOf(logType) + " " + message); + } + + public File getLogDirctory() { + return this.logDir; + } +} diff --git a/src/main/java/com/geotwo/webserver/core/map/LayerFactory.java b/src/main/java/com/geotwo/webserver/core/map/LayerFactory.java new file mode 100644 index 0000000..b9ee57f --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/map/LayerFactory.java @@ -0,0 +1,82 @@ +package com.geotwo.webserver.core.map; + +import com.geotwo.webserver.core.map.layer.FeatureLayer; +import com.geotwo.webserver.core.map.layer.GroupLayer; +import com.geotwo.webserver.core.map.layer.Layer; +import com.geotwo.webserver.core.map.layer.O2DemLayer; +import com.geotwo.webserver.core.map.layer.O2ImgLayer; +import com.geotwo.webserver.core.map.layer.WCSLayer; +import com.geotwo.webserver.core.map.layer.WMSLayer; +import com.geotwo.webserver.core.util.AVList; + +public class LayerFactory { + public enum LayerType { + JDBC("VECTOR_JDBC", ".jdbc"), + SHAPE("VECTOR_SHAPE", ".shape"), + GEOWAVE("VECTOR_GEOWAVE", ".gwave"), + GROUP("VECTOR_GROUP", ".group"), + O2WPSVEC("VECTOR_O2WPS", ".o2wpsvec"), + O2WPSCOV("COVERAGE_O2WPS", ".o2wpscov"), + WMS("LINK_WMS", ".wms"), + WCS("LINK_WCS", ".wcs"), + O2IMG("RASTER_O2IMG", ".o2img"), + O2DEM("RASTER_O2DEM", ".o2dem"); + + private String type; + + private String pre; + + LayerType(String type, String pre) { + this.type = type; + this.pre = pre; + } + + public String getType() { + return this.type; + } + + public String getPrefix() { + return this.pre; + } + + public String toString() { + return getType(); + } + } + + public static Layer createLayer(LayerType type, AVList params) throws Exception { + switch (type) { + case JDBC: + params.setValue("conf.service.layer.type", LayerType.JDBC); + return (Layer)new FeatureLayer(params); + case SHAPE: + params.setValue("conf.service.layer.type", LayerType.SHAPE); + return (Layer)new FeatureLayer(params); + case GEOWAVE: + params.setValue("conf.service.layer.type", LayerType.GEOWAVE); + return (Layer)new FeatureLayer(params); + case O2WPSVEC: + params.setValue("conf.service.layer.type", LayerType.O2WPSVEC); + return (Layer)new FeatureLayer(params); + case O2WPSCOV: + params.setValue("conf.service.layer.type", LayerType.O2WPSCOV); + return (Layer)new O2DemLayer(params); + case GROUP: + params.setValue("conf.service.layer.type", LayerType.GROUP); + return (Layer)new GroupLayer(params); + case WMS: + params.setValue("conf.service.layer.type", LayerType.WMS); + return (Layer)new WMSLayer(params); + case WCS: + params.setValue("conf.service.layer.type", LayerType.WCS); + return (Layer)new WCSLayer(params); + case O2IMG: + params.setValue("conf.service.layer.type", LayerType.O2IMG); + return (Layer)new O2ImgLayer(params); + case O2DEM: + params.setValue("conf.service.layer.type", LayerType.O2DEM); + return (Layer)new O2DemLayer(params); + } + throw new IllegalArgumentException("LayerType [" + type + "] is not support."); + } +} diff --git a/src/main/java/com/geotwo/webserver/core/map/LayerSet.java b/src/main/java/com/geotwo/webserver/core/map/LayerSet.java new file mode 100644 index 0000000..562222f --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/map/LayerSet.java @@ -0,0 +1,115 @@ +package com.geotwo.webserver.core.map; + +import com.geotwo.webserver.core.map.layer.Layer; +import com.geotwo.webserver.core.util.ServerUtil; +import java.util.ArrayList; +import java.util.HashMap; + +public class LayerSet { + private final Map serviceMap; + + private HashMap layerStore = new HashMap(); + + public LayerSet(Map map) { + this.serviceMap = map; + } + + public void addLayer(Layer layer, boolean overWrite) throws Exception { + if (layer == null || ServerUtil.isNullString(layer.getName())) + throw new IllegalArgumentException("Layer object or Layer name is NULL."); + if (!overWrite && this.layerStore.containsKey(layer.getName())) + throw new IllegalArgumentException("Layer [" + layer.getName() + "] is already exist."); + this.layerStore.put(layer.getName(), layer); + } + + public void addLayers(ArrayList layers, boolean overWrite) throws Exception { + if (layers == null) + throw new IllegalArgumentException("Layers object is NULL."); + for (Layer layer : layers) { + if (!overWrite && this.layerStore.containsKey(layer.getName())) + continue; + this.layerStore.put(layer.getName(), layer); + } + } + + public boolean isExistLayer(String name) { + if (ServerUtil.isNullString(name)) + return false; + name = name.trim().toUpperCase(); + return this.layerStore.containsKey(name); + } + + public Layer getLayer(String name) throws Exception { + if (ServerUtil.isNullString(name)) + throw new IllegalArgumentException("Layer Name [" + name + "] is NULL."); + name = name.trim().toUpperCase(); + Layer layer = this.layerStore.get(name); + if (layer == null) + throw new NullPointerException("Layer [" + name + "] is not exist in ServiceMap [" + this.serviceMap.getName() + "]"); + return layer; + } + + public ArrayList getLayers() { + return new ArrayList(this.layerStore.values()); + } + + public ArrayList getLayers(LayerFactory.LayerType type) { + ArrayList layers = new ArrayList(); + for (Layer layer : this.layerStore.values()) { + if (layer.getLayerType() == type) + layers.add(layer); + } + return layers; + } + + public void removeLayers() { + this.layerStore.clear(); + } + + public Layer removeLayer(String name) throws Exception { + Layer layer = getLayer(name); + this.layerStore.remove(layer.getName()); + return layer; + } + + public ArrayList removeLayer(LayerFactory.LayerType type) throws Exception { + ArrayList layers = getLayers(type); + for (Layer layer : layers) + this.layerStore.remove(layer.getName()); + return layers; + } + + public ArrayList removeLayer(LayerFactory.LayerType type, String serverName) throws Exception { + if (ServerUtil.isNullString(serverName)) + throw new IllegalArgumentException("Server Name [" + serverName + "] is NULL."); + serverName = serverName.trim(); + ArrayList resultList = new ArrayList(); + ArrayList layers = getLayers(type); + for (Layer layer : layers) { + if (layer.getServerName().equalsIgnoreCase(serverName)) { + this.layerStore.remove(layer.getName()); + resultList.add(layer); + } + } + return resultList; + } + + public ArrayList removeLayer(LayerFactory.LayerType type, String serverName, String sourceName) throws Exception { + if (ServerUtil.isNullString(serverName)) + throw new IllegalArgumentException("Server Name [" + serverName + "] is NULL."); + serverName = serverName.trim(); + if (ServerUtil.isNullString(sourceName)) + throw new IllegalArgumentException("Source Name [" + sourceName + "] is NULL."); + sourceName = sourceName.trim(); + ArrayList resultList = new ArrayList(); + ArrayList layers = getLayers(type); + for (Layer layer : layers) { + if (layer.getServerName().equalsIgnoreCase(serverName) && + layer.getSourceName().equalsIgnoreCase(sourceName)) { + this.layerStore.remove(layer.getName()); + resultList.add(layer); + } + } + return resultList; + } +} diff --git a/src/main/java/com/geotwo/webserver/core/map/Map.java b/src/main/java/com/geotwo/webserver/core/map/Map.java new file mode 100644 index 0000000..eb330ee --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/map/Map.java @@ -0,0 +1,95 @@ +package com.geotwo.webserver.core.map; + +import com.geotwo.webserver.core.map.layer.Layer; +import com.geotwo.webserver.core.util.ServerUtil; +import com.geotwo.webserver.core.vector.WpsVecStoreMngr; +import com.geotwo.webserver.core.vector.o2wps.O2WpsLayerSet; +import java.util.ArrayList; + +public class Map { + private final String mapName; + + private final String mapNameSpace; + + private LayerSet serviceLayerSet; + + private O2WpsLayerSet o2wpsLayerSet; + + public Map(String name, String ns) throws Exception { + if (ServerUtil.isNullString(name)) + throw new IllegalArgumentException("Map Name [" + name + "] is NULL."); + this.mapName = name.trim().toUpperCase(); + if (!ServerUtil.isNullString(ns)) { + ns = ns.trim(); + if (ns.equalsIgnoreCase("NULL") || ns.equalsIgnoreCase("DEFAULT")) { + this.mapNameSpace = null; + } else { + this.mapNameSpace = ns; + } + } else { + this.mapNameSpace = null; + } + this.serviceLayerSet = new LayerSet(this); + this.o2wpsLayerSet = new O2WpsLayerSet(WpsVecStoreMngr.O2WpsMetaTableType.LAYERINFO_TBL.toString()); + } + + public String getName() { + return this.mapName; + } + + public boolean useNameSpace() { + if (ServerUtil.isNullString(this.mapNameSpace)) + return false; + return true; + } + + public String getNameSpace() { + if (useNameSpace()) + return this.mapName.toLowerCase(); + return "sf"; + } + + public String getNameSpaceURI() { + if (useNameSpace()) + return this.mapNameSpace; + return "http://cite.opengeospatial.org/gmlsf"; + } + + public LayerSet getServiceLayerSet() { + return this.serviceLayerSet; + } + + public O2WpsLayerSet getO2WpsLayerSet() { + return this.o2wpsLayerSet; + } + + public ArrayList getAllLayers() { + ArrayList layers = new ArrayList(); + layers.addAll(this.serviceLayerSet.getLayers()); + layers.addAll(this.o2wpsLayerSet.getLayers()); + return layers; + } + + public Layer getLayer(String name) throws Exception { + try { + return this.serviceLayerSet.getLayer(name); + } catch (Exception e) { + Layer layer = this.o2wpsLayerSet.getLayer(name); + if (layer != null) + return layer; + layer = this.o2wpsLayerSet.getLayer(WpsVecStoreMngr.O2WpsMetaTableType.STORELYRINFO_TBL.getName(), name); + if (layer != null) + return layer; + layer = this.o2wpsLayerSet.getLayer(WpsVecStoreMngr.O2WpsMetaTableType.SHARELYRINFO_TBL.getName(), name); + return layer; + } + } + + public Layer getLayer(String storeTableName, String name) throws Exception { + try { + return this.o2wpsLayerSet.getLayer(storeTableName, name); + } catch (Exception e) { + return null; + } + } +} diff --git a/src/main/java/com/geotwo/webserver/core/map/layer/FeatureLayer.java b/src/main/java/com/geotwo/webserver/core/map/layer/FeatureLayer.java new file mode 100644 index 0000000..19a6fd0 --- /dev/null +++ b/src/main/java/com/geotwo/webserver/core/map/layer/FeatureLayer.java @@ -0,0 +1,357 @@ +package com.geotwo.webserver.core.map.layer; + +import com.geotwo.webserver.core.ServerContext; +import com.geotwo.webserver.core.log.LogMngr; +import com.geotwo.webserver.core.render.RefineRenderStyleVisitor; +import com.geotwo.webserver.core.render.StyleMngr; +import com.geotwo.webserver.core.util.AVList; +import com.geotwo.webserver.core.util.ServerUtil; +import com.geotwo.webserver.core.vector.O2DSMngr; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.concurrent.ConcurrentHashMap; +import org.geotools.data.simple.SimpleFeatureSource; +import org.geotools.geometry.jts.ReferencedEnvelope; +import org.geotools.referencing.CRS; +import org.geotools.styling.NamedLayer; +import org.geotools.styling.Style; +import org.geotools.styling.StyleVisitor; +import org.geotools.styling.StyledLayer; +import org.geotools.styling.StyledLayerDescriptor; +import org.geotools.styling.UserLayer; +import org.opengis.feature.simple.SimpleFeatureType; +import org.opengis.filter.Filter; + +public class FeatureLayer extends Layer { + private final String sourceName; + + private ReferencedEnvelope bbox; + + private ConcurrentHashMap styleStore = new ConcurrentHashMap(); + + private Style currentStyle; + + private ConcurrentHashMap renderStyles = new ConcurrentHashMap(); + + public FeatureLayer(AVList params) throws Exception { + super(params); + try { + String sVal = params.getStringValue("conf.service.ref.source"); + sVal = sVal.trim().toUpperCase(); + this.sourceName = sVal; + SimpleFeatureSource featureSource = O2DSMngr.getFeatureSource(getLayerType(), getServerName(), getSourceName()); + this.bbox = featureSource.getBounds(); + } catch (Exception e) { + throw e; + } + if (params.getValue("conf.service.sld") == null) { + Style style = StyleMngr.getDefaultUserStyle(getLayerType(), getServerName(), getSourceName(), getName()); + setCurrentStyle(style); + LogMngr.getInstance().logDebug("[LAYER]", + "Set Style Use Default :: [Map:" + ServerContext.getMap().getName() + "/Layer:" + getName() + "]"); + } else { + StyledLayerDescriptor styledLayerDescriptor = (StyledLayerDescriptor)params.getValue("conf.service.sld"); + initServiceStyle(styledLayerDescriptor, false); + LogMngr.getInstance().logDebug("[LAYER]", + "Set Style From DB :: [Map:" + ServerContext.getMap().getName() + "/Layer:" + getName() + "]"); + } + LogMngr.getInstance().logDebug("[LAYER]", + "Default Style Name Is [" + getCurrentStyle().getName() + "] :: [Map:" + ServerContext.getMap().getName() + "/Layer:" + getName() + "]"); + StyledLayerDescriptor sld = StyleMngr.readServiceSLD(getName()); + if (sld != null) { + initServiceStyle(sld, false); + LogMngr.getInstance().logDebug("[LAYER]", + "Override Style From SLD FILE :: [Map:" + ServerContext.getMap().getName() + "/Layer:" + getName() + "]"); + LogMngr.getInstance().logDebug("[LAYER]", + "Default Style Name Is [" + getCurrentStyle().getName() + "] :: [Map:" + ServerContext.getMap().getName() + "/Layer:" + getName() + "]"); + } + try { + if (isUseCache().booleanValue()) { + O2DSMngr.putMemoryFeatureSource(getLayerType(), getServerName(), getSourceName(), (Filter)Filter.INCLUDE); + LogMngr.getInstance().logDebug("[LAYER]", + "Now use memery DataStore :: [Map:" + ServerContext.getMap().getName() + "/Layer:" + getName() + "]"); + } + } catch (Exception e) { + LogMngr.getInstance().logDebug("[LAYER]", + "Fail to make memery DataStore. Now use common DataStore :: [Map:" + ServerContext.getMap().getName() + "/Layer:" + getName() + "]"); + } + } + + public synchronized void reloadServiceStyle() { + StyledLayerDescriptor sld = StyleMngr.readServiceSLD(getName()); + if (sld != null) { + initServiceStyle(sld, false); + LogMngr.getInstance().logDebug("[LAYER]", + "Reload Style From SLD FILE :: [Map:" + getMapName() + "/Layer:" + getName() + "]"); + LogMngr.getInstance().logDebug("[LAYER]", + "Default Style Name Is [" + getCurrentStyle().getName() + "] :: [Map:" + getMapName() + "/Layer:" + getName() + "]"); + } + } + + public synchronized void initServiceStyle(StyledLayerDescriptor sld, boolean write) { + Style defaultStyle = null; + ConcurrentHashMap tempStore = new ConcurrentHashMap(); + Iterator iterLayer = sld.layers().iterator(); + while (iterLayer.hasNext()) { + StyledLayer styledLayer = iterLayer.next(); + if (!ServerUtil.isNullString(styledLayer.getName()) && + !styledLayer.getName().equalsIgnoreCase(getName())) + continue; + Iterator