TabooMan!
This commit is contained in:
		
							
								
								
									
										21
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -20,7 +20,20 @@
 | 
			
		||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
 | 
			
		||||
hs_err_pid*
 | 
			
		||||
.gradle/4.3.1/
 | 
			
		||||
.idea/TabooLib.iml
 | 
			
		||||
.idea/misc.xml
 | 
			
		||||
.idea/modules.xml
 | 
			
		||||
.idea/workspace.xml
 | 
			
		||||
.idea
 | 
			
		||||
target/TabooLib-3.832-shaded.jar
 | 
			
		||||
target/TabooLib-3.832.jar
 | 
			
		||||
target/classes/JavaShells/
 | 
			
		||||
target/classes/Language/
 | 
			
		||||
target/classes/Language2/
 | 
			
		||||
target/classes/TLM/
 | 
			
		||||
target/classes/config.yml
 | 
			
		||||
target/classes/internalLang.yml
 | 
			
		||||
target/classes/items.yml
 | 
			
		||||
target/classes/lang/
 | 
			
		||||
target/classes/module.yml
 | 
			
		||||
target/classes/plugin.yml
 | 
			
		||||
target/generated-sources/
 | 
			
		||||
target/maven-archiver/
 | 
			
		||||
target/maven-status/
 | 
			
		||||
target/original-TabooLib-3.832.jar
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								.idea/inspectionProfiles/Project_Default.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1
									
								
								.idea/inspectionProfiles/Project_Default.xml
									
									
									
										generated
									
									
									
								
							@@ -10,6 +10,7 @@
 | 
			
		||||
    <inspection_tool class="AlibabaClassNamingShouldBeCamel" enabled="false" level="MAJOR" enabled_by_default="false" />
 | 
			
		||||
    <inspection_tool class="AlibabaConstantFieldShouldBeUpperCase" enabled="false" level="CRITICAL" enabled_by_default="false" />
 | 
			
		||||
    <inspection_tool class="AlibabaEnumConstantsMustHaveComment" enabled="false" level="CRITICAL" enabled_by_default="false" />
 | 
			
		||||
    <inspection_tool class="AlibabaThreadPoolCreation" enabled="false" level="BLOCKER" enabled_by_default="false" />
 | 
			
		||||
    <inspection_tool class="AlibabaUndefineMagicConstant" enabled="false" level="MAJOR" enabled_by_default="false" />
 | 
			
		||||
    <inspection_tool class="JavaDoc" enabled="false" level="WARNING" enabled_by_default="false">
 | 
			
		||||
      <option name="TOP_LEVEL_CLASS_OPTIONS">
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										13
									
								
								.idea/libraries/Maven__com_h2database_h2_1_4_197.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								.idea/libraries/Maven__com_h2database_h2_1_4_197.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
<component name="libraryTable">
 | 
			
		||||
  <library name="Maven: com.h2database:h2:1.4.197">
 | 
			
		||||
    <CLASSES>
 | 
			
		||||
      <root url="jar://$MAVEN_REPOSITORY$/com/h2database/h2/1.4.197/h2-1.4.197.jar!/" />
 | 
			
		||||
    </CLASSES>
 | 
			
		||||
    <JAVADOC>
 | 
			
		||||
      <root url="jar://$MAVEN_REPOSITORY$/com/h2database/h2/1.4.197/h2-1.4.197-javadoc.jar!/" />
 | 
			
		||||
    </JAVADOC>
 | 
			
		||||
    <SOURCES>
 | 
			
		||||
      <root url="jar://$MAVEN_REPOSITORY$/com/h2database/h2/1.4.197/h2-1.4.197-sources.jar!/" />
 | 
			
		||||
    </SOURCES>
 | 
			
		||||
  </library>
 | 
			
		||||
</component>
 | 
			
		||||
							
								
								
									
										13
									
								
								.idea/libraries/Maven__javax_servlet_servlet_api_2_5.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								.idea/libraries/Maven__javax_servlet_servlet_api_2_5.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
<component name="libraryTable">
 | 
			
		||||
  <library name="Maven: javax.servlet:servlet-api:2.5">
 | 
			
		||||
    <CLASSES>
 | 
			
		||||
      <root url="jar://$MAVEN_REPOSITORY$/javax/servlet/servlet-api/2.5/servlet-api-2.5.jar!/" />
 | 
			
		||||
    </CLASSES>
 | 
			
		||||
    <JAVADOC>
 | 
			
		||||
      <root url="jar://$MAVEN_REPOSITORY$/javax/servlet/servlet-api/2.5/servlet-api-2.5-javadoc.jar!/" />
 | 
			
		||||
    </JAVADOC>
 | 
			
		||||
    <SOURCES>
 | 
			
		||||
      <root url="jar://$MAVEN_REPOSITORY$/javax/servlet/servlet-api/2.5/servlet-api-2.5-sources.jar!/" />
 | 
			
		||||
    </SOURCES>
 | 
			
		||||
  </library>
 | 
			
		||||
</component>
 | 
			
		||||
							
								
								
									
										13
									
								
								.idea/libraries/Maven__org_codehaus_jackson_jackson_core_asl_1_9_13.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								.idea/libraries/Maven__org_codehaus_jackson_jackson_core_asl_1_9_13.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
<component name="libraryTable">
 | 
			
		||||
  <library name="Maven: org.codehaus.jackson:jackson-core-asl:1.9.13">
 | 
			
		||||
    <CLASSES>
 | 
			
		||||
      <root url="jar://$MAVEN_REPOSITORY$/org/codehaus/jackson/jackson-core-asl/1.9.13/jackson-core-asl-1.9.13.jar!/" />
 | 
			
		||||
    </CLASSES>
 | 
			
		||||
    <JAVADOC>
 | 
			
		||||
      <root url="jar://$MAVEN_REPOSITORY$/org/codehaus/jackson/jackson-core-asl/1.9.13/jackson-core-asl-1.9.13-javadoc.jar!/" />
 | 
			
		||||
    </JAVADOC>
 | 
			
		||||
    <SOURCES>
 | 
			
		||||
      <root url="jar://$MAVEN_REPOSITORY$/org/codehaus/jackson/jackson-core-asl/1.9.13/jackson-core-asl-1.9.13-sources.jar!/" />
 | 
			
		||||
    </SOURCES>
 | 
			
		||||
  </library>
 | 
			
		||||
</component>
 | 
			
		||||
							
								
								
									
										13
									
								
								.idea/libraries/Maven__org_codehaus_jackson_jackson_mapper_asl_1_9_13.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								.idea/libraries/Maven__org_codehaus_jackson_jackson_mapper_asl_1_9_13.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
<component name="libraryTable">
 | 
			
		||||
  <library name="Maven: org.codehaus.jackson:jackson-mapper-asl:1.9.13">
 | 
			
		||||
    <CLASSES>
 | 
			
		||||
      <root url="jar://$MAVEN_REPOSITORY$/org/codehaus/jackson/jackson-mapper-asl/1.9.13/jackson-mapper-asl-1.9.13.jar!/" />
 | 
			
		||||
    </CLASSES>
 | 
			
		||||
    <JAVADOC>
 | 
			
		||||
      <root url="jar://$MAVEN_REPOSITORY$/org/codehaus/jackson/jackson-mapper-asl/1.9.13/jackson-mapper-asl-1.9.13-javadoc.jar!/" />
 | 
			
		||||
    </JAVADOC>
 | 
			
		||||
    <SOURCES>
 | 
			
		||||
      <root url="jar://$MAVEN_REPOSITORY$/org/codehaus/jackson/jackson-mapper-asl/1.9.13/jackson-mapper-asl-1.9.13-sources.jar!/" />
 | 
			
		||||
    </SOURCES>
 | 
			
		||||
  </library>
 | 
			
		||||
</component>
 | 
			
		||||
							
								
								
									
										13
									
								
								.idea/libraries/Maven__org_javalite_activejdbc_2_0.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								.idea/libraries/Maven__org_javalite_activejdbc_2_0.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
<component name="libraryTable">
 | 
			
		||||
  <library name="Maven: org.javalite:activejdbc:2.0">
 | 
			
		||||
    <CLASSES>
 | 
			
		||||
      <root url="jar://$MAVEN_REPOSITORY$/org/javalite/activejdbc/2.0/activejdbc-2.0.jar!/" />
 | 
			
		||||
    </CLASSES>
 | 
			
		||||
    <JAVADOC>
 | 
			
		||||
      <root url="jar://$MAVEN_REPOSITORY$/org/javalite/activejdbc/2.0/activejdbc-2.0-javadoc.jar!/" />
 | 
			
		||||
    </JAVADOC>
 | 
			
		||||
    <SOURCES>
 | 
			
		||||
      <root url="jar://$MAVEN_REPOSITORY$/org/javalite/activejdbc/2.0/activejdbc-2.0-sources.jar!/" />
 | 
			
		||||
    </SOURCES>
 | 
			
		||||
  </library>
 | 
			
		||||
</component>
 | 
			
		||||
							
								
								
									
										13
									
								
								.idea/libraries/Maven__org_javalite_app_config_2_0.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								.idea/libraries/Maven__org_javalite_app_config_2_0.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
<component name="libraryTable">
 | 
			
		||||
  <library name="Maven: org.javalite:app-config:2.0">
 | 
			
		||||
    <CLASSES>
 | 
			
		||||
      <root url="jar://$MAVEN_REPOSITORY$/org/javalite/app-config/2.0/app-config-2.0.jar!/" />
 | 
			
		||||
    </CLASSES>
 | 
			
		||||
    <JAVADOC>
 | 
			
		||||
      <root url="jar://$MAVEN_REPOSITORY$/org/javalite/app-config/2.0/app-config-2.0-javadoc.jar!/" />
 | 
			
		||||
    </JAVADOC>
 | 
			
		||||
    <SOURCES>
 | 
			
		||||
      <root url="jar://$MAVEN_REPOSITORY$/org/javalite/app-config/2.0/app-config-2.0-sources.jar!/" />
 | 
			
		||||
    </SOURCES>
 | 
			
		||||
  </library>
 | 
			
		||||
</component>
 | 
			
		||||
							
								
								
									
										13
									
								
								.idea/libraries/Maven__org_javalite_javalite_common_2_0.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								.idea/libraries/Maven__org_javalite_javalite_common_2_0.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
<component name="libraryTable">
 | 
			
		||||
  <library name="Maven: org.javalite:javalite-common:2.0">
 | 
			
		||||
    <CLASSES>
 | 
			
		||||
      <root url="jar://$MAVEN_REPOSITORY$/org/javalite/javalite-common/2.0/javalite-common-2.0.jar!/" />
 | 
			
		||||
    </CLASSES>
 | 
			
		||||
    <JAVADOC>
 | 
			
		||||
      <root url="jar://$MAVEN_REPOSITORY$/org/javalite/javalite-common/2.0/javalite-common-2.0-javadoc.jar!/" />
 | 
			
		||||
    </JAVADOC>
 | 
			
		||||
    <SOURCES>
 | 
			
		||||
      <root url="jar://$MAVEN_REPOSITORY$/org/javalite/javalite-common/2.0/javalite-common-2.0-sources.jar!/" />
 | 
			
		||||
    </SOURCES>
 | 
			
		||||
  </library>
 | 
			
		||||
</component>
 | 
			
		||||
							
								
								
									
										16
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								pom.xml
									
									
									
									
									
								
							@@ -67,6 +67,22 @@
 | 
			
		||||
            <artifactId>HikariCP</artifactId>
 | 
			
		||||
            <version>3.1.0</version>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.javalite</groupId>
 | 
			
		||||
            <artifactId>activejdbc</artifactId>
 | 
			
		||||
            <version>2.0</version>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>javax.servlet</groupId>
 | 
			
		||||
            <artifactId>servlet-api</artifactId>
 | 
			
		||||
            <version>2.5</version>
 | 
			
		||||
            <scope>provided</scope>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>com.h2database</groupId>
 | 
			
		||||
            <artifactId>h2</artifactId>
 | 
			
		||||
            <version>1.4.197</version>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>com.ilummc.eagletdl</groupId>
 | 
			
		||||
            <artifactId>EagletCore</artifactId>
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ package com.ilummc.tlib;
 | 
			
		||||
import com.ilummc.tlib.annotations.Dependency;
 | 
			
		||||
import com.ilummc.tlib.compat.PlaceholderHook;
 | 
			
		||||
import com.ilummc.tlib.config.TLibConfig;
 | 
			
		||||
import com.ilummc.tlib.db.Pool;
 | 
			
		||||
import com.ilummc.tlib.filter.TLoggerFilter;
 | 
			
		||||
import com.ilummc.tlib.inject.TConfigWatcher;
 | 
			
		||||
import com.ilummc.tlib.inject.TDependencyInjector;
 | 
			
		||||
@@ -24,6 +25,16 @@ import java.nio.charset.Charset;
 | 
			
		||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "org.ow2.asm:asm:6.1.1")
 | 
			
		||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "com.zaxxer:HikariCP:3.1.0")
 | 
			
		||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "org.slf4j:slf4j-api:1.7.25")
 | 
			
		||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "org.javalite:activejdbc:2.0")
 | 
			
		||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "org.javalite:javalite-common:2.0")
 | 
			
		||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "org.javalite:app-config:2.0")
 | 
			
		||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "org.codehaus.jackson:jackson-mapper-asl:1.9.13")
 | 
			
		||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "org.codehaus.jackson:jackson-core-asl:1.9.13")
 | 
			
		||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "jaxen:jaxen:1.1.6")
 | 
			
		||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "dom4j:dom4j:1.6.1")
 | 
			
		||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "xml-apis:xml-apis:1.0.b2")
 | 
			
		||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "org.ehcache:ehcache:3.5.2")
 | 
			
		||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "com.h2database:h2:1.4.197")
 | 
			
		||||
public class TLib {
 | 
			
		||||
 | 
			
		||||
    private static TLib tLib;
 | 
			
		||||
@@ -60,10 +71,20 @@ public class TLib {
 | 
			
		||||
        TLoggerFilter.init();
 | 
			
		||||
        TLocaleLoader.init();
 | 
			
		||||
        PlaceholderHook.init();
 | 
			
		||||
        TLocaleLoader.load(Main.getInst(), false);
 | 
			
		||||
        TDependencyInjector.inject(Main.getInst(), tLib);
 | 
			
		||||
 | 
			
		||||
        // init database
 | 
			
		||||
        try {
 | 
			
		||||
            Pool.init();
 | 
			
		||||
        } catch (Throwable e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void unload() {
 | 
			
		||||
        Pool.unload();
 | 
			
		||||
        tLib.getConfigWatcher().unregisterAll();
 | 
			
		||||
        TDependencyInjector.eject(Main.getInst(), tLib);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -9,13 +9,28 @@ import com.ilummc.tlib.annotations.TConfig;
 | 
			
		||||
@TConfig(name = "tlib.yml", listenChanges = true)
 | 
			
		||||
public class TLibConfig {
 | 
			
		||||
 | 
			
		||||
    private boolean enablePlaceholderHookByDefault = false;
 | 
			
		||||
    @Getter
 | 
			
		||||
    private String dataSourceClassName;
 | 
			
		||||
 | 
			
		||||
    public void setEnablePlaceholderHookByDefault(boolean enablePlaceholderHookByDefault) {
 | 
			
		||||
        this.enablePlaceholderHookByDefault = enablePlaceholderHookByDefault;
 | 
			
		||||
    }
 | 
			
		||||
    @Getter
 | 
			
		||||
    private String jdbcUrl = "jdbc:h2:file:~/plugins/TabooLib/h2";
 | 
			
		||||
 | 
			
		||||
    @Getter
 | 
			
		||||
    private String driverClassName;
 | 
			
		||||
 | 
			
		||||
    @Getter
 | 
			
		||||
    private String username = "";
 | 
			
		||||
 | 
			
		||||
    @Getter
 | 
			
		||||
    private String password = "";
 | 
			
		||||
 | 
			
		||||
    @Getter
 | 
			
		||||
    private int maximumPoolSize = 4;
 | 
			
		||||
 | 
			
		||||
    @Getter
 | 
			
		||||
    private Map<String, Object> settings = new HashMap<String, Object>() {{
 | 
			
		||||
        put("cachePrepStmts", true);
 | 
			
		||||
        put("useServerPrepStmts", true);
 | 
			
		||||
    }};
 | 
			
		||||
 | 
			
		||||
    public boolean isEnablePlaceholderHookByDefault() {
 | 
			
		||||
        return enablePlaceholderHookByDefault;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										61
									
								
								src/main/java/com/ilummc/tlib/db/Pool.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								src/main/java/com/ilummc/tlib/db/Pool.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
package com.ilummc.tlib.db;
 | 
			
		||||
 | 
			
		||||
import com.ilummc.tlib.TLib;
 | 
			
		||||
import com.ilummc.tlib.resources.TLocale;
 | 
			
		||||
import org.javalite.activejdbc.Base;
 | 
			
		||||
 | 
			
		||||
import java.util.concurrent.LinkedBlockingQueue;
 | 
			
		||||
import java.util.concurrent.ThreadPoolExecutor;
 | 
			
		||||
import java.util.concurrent.TimeUnit;
 | 
			
		||||
import java.util.concurrent.atomic.AtomicInteger;
 | 
			
		||||
 | 
			
		||||
public final class Pool extends ThreadPoolExecutor {
 | 
			
		||||
 | 
			
		||||
    private static final AtomicInteger number = new AtomicInteger(1);
 | 
			
		||||
 | 
			
		||||
    private static final Pool singleton = new Pool();
 | 
			
		||||
 | 
			
		||||
    private final TLibDataSource dataSource;
 | 
			
		||||
 | 
			
		||||
    private Pool() {
 | 
			
		||||
        super(TLib.getTLib().getConfig().getMaximumPoolSize(),
 | 
			
		||||
                TLib.getTLib().getConfig().getMaximumPoolSize(),
 | 
			
		||||
                0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
 | 
			
		||||
        try {
 | 
			
		||||
            dataSource = new TLibDataSource();
 | 
			
		||||
            this.setThreadFactory(r -> new Thread(() -> {
 | 
			
		||||
                Base.open(dataSource.getDataSource());
 | 
			
		||||
                r.run();
 | 
			
		||||
            }, "TabooLib-DbPool-" + number.getAndIncrement()));
 | 
			
		||||
            prestartAllCoreThreads();
 | 
			
		||||
            TLocale.sendToConsole("DATABASE.CONNECTION-ESTABLISHED", dataSource.getDataSource().getConnection().getMetaData().getDatabaseProductName(),
 | 
			
		||||
                    String.valueOf(TLib.getTLib().getConfig().getMaximumPoolSize()));
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            TLocale.sendToConsole("DATABASE.CONNECTION-ERROR", e.toString());
 | 
			
		||||
            throw new RuntimeException();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void run(Runnable runnable) {
 | 
			
		||||
        instance().execute(runnable);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void init() {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void unload() {
 | 
			
		||||
        instance().dataSource.disconnect();
 | 
			
		||||
        instance().shutdown();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Pool instance() {
 | 
			
		||||
        return singleton;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void afterExecute(Runnable r, Throwable t) {
 | 
			
		||||
        if (t != null) Base.close();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										35
									
								
								src/main/java/com/ilummc/tlib/db/TLibDataSource.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/main/java/com/ilummc/tlib/db/TLibDataSource.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
package com.ilummc.tlib.db;
 | 
			
		||||
 | 
			
		||||
import com.ilummc.tlib.TLib;
 | 
			
		||||
import com.zaxxer.hikari.HikariConfig;
 | 
			
		||||
import com.zaxxer.hikari.HikariDataSource;
 | 
			
		||||
import org.javalite.activejdbc.Base;
 | 
			
		||||
 | 
			
		||||
import javax.sql.DataSource;
 | 
			
		||||
import java.util.Properties;
 | 
			
		||||
 | 
			
		||||
public class TLibDataSource {
 | 
			
		||||
 | 
			
		||||
    private final HikariDataSource dataSource;
 | 
			
		||||
 | 
			
		||||
    TLibDataSource() {
 | 
			
		||||
        Properties properties = new Properties();
 | 
			
		||||
        properties.put("jdbcUrl", TLib.getTLib().getConfig().getJdbcUrl());
 | 
			
		||||
        properties.put("username", TLib.getTLib().getConfig().getUsername());
 | 
			
		||||
        properties.put("password", TLib.getTLib().getConfig().getPassword());
 | 
			
		||||
        properties.put("dataSourceClassName", TLib.getTLib().getConfig().getDataSourceClassName());
 | 
			
		||||
        properties.put("driverClassName", TLib.getTLib().getConfig().getDriverClassName());
 | 
			
		||||
        TLib.getTLib().getConfig().getSettings().forEach((k, v) -> properties.put("dataSource." + k, v));
 | 
			
		||||
        dataSource = new HikariDataSource(new HikariConfig(properties));
 | 
			
		||||
        Base.open(dataSource);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public DataSource getDataSource() {
 | 
			
		||||
        return dataSource;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void disconnect() {
 | 
			
		||||
        Base.close();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,6 +1,8 @@
 | 
			
		||||
package com.ilummc.tlib.inject;
 | 
			
		||||
 | 
			
		||||
import com.google.common.io.Files;
 | 
			
		||||
import com.google.gson.Gson;
 | 
			
		||||
import com.google.gson.GsonBuilder;
 | 
			
		||||
import com.ilummc.tlib.annotations.TConfig;
 | 
			
		||||
import com.ilummc.tlib.resources.TLocale;
 | 
			
		||||
import me.skymc.taboolib.fileutils.ConfigUtils;
 | 
			
		||||
@@ -8,12 +10,12 @@ import org.apache.commons.lang3.Validate;
 | 
			
		||||
import org.bukkit.configuration.file.YamlConfiguration;
 | 
			
		||||
import org.bukkit.plugin.Plugin;
 | 
			
		||||
import org.yaml.snakeyaml.DumperOptions;
 | 
			
		||||
import org.yaml.snakeyaml.Yaml;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
import java.nio.charset.Charset;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
public class TConfigInjector {
 | 
			
		||||
@@ -106,7 +108,7 @@ public class TConfigInjector {
 | 
			
		||||
        try {
 | 
			
		||||
            TConfig config = object.getClass().getAnnotation(TConfig.class);
 | 
			
		||||
            Validate.notNull(config);
 | 
			
		||||
            return ConfigUtils.objToConf(object).getValues(false);
 | 
			
		||||
            return ConfigUtils.objToMap(ConfigUtils.objToConf(object).getValues(false), config.excludeModifiers());
 | 
			
		||||
        } catch (NullPointerException e) {
 | 
			
		||||
            TLocale.Logger.warn("CONFIG.SAVE-FAIL-NO-ANNOTATION", plugin.toString(), object.getClass().getSimpleName());
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
@@ -118,16 +120,12 @@ public class TConfigInjector {
 | 
			
		||||
    public static void saveConfig(Plugin plugin, Object object) throws IOException, NullPointerException {
 | 
			
		||||
        TConfig config = object.getClass().getAnnotation(TConfig.class);
 | 
			
		||||
        Validate.notNull(config);
 | 
			
		||||
        Object obj = serialize(plugin, object);
 | 
			
		||||
        Validate.notNull(obj);
 | 
			
		||||
        Gson gson = new GsonBuilder().disableHtmlEscaping().create();
 | 
			
		||||
        Map map = gson.fromJson(gson.toJson(object), HashMap.class);
 | 
			
		||||
        YamlConfiguration configuration = (YamlConfiguration) ConfigUtils.mapToConf(map);
 | 
			
		||||
        File target = new File(plugin.getDataFolder(), config.name());
 | 
			
		||||
        if (!target.exists()) target.createNewFile();
 | 
			
		||||
        DumperOptions options = new DumperOptions();
 | 
			
		||||
        options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
 | 
			
		||||
        options.setAllowUnicode(false);
 | 
			
		||||
        Yaml yaml = new Yaml(options);
 | 
			
		||||
        String str = yaml.dump(obj);
 | 
			
		||||
        byte[] arr = str.getBytes(config.charset());
 | 
			
		||||
        byte[] arr = configuration.saveToString().getBytes(config.charset());
 | 
			
		||||
        Files.write(arr, target);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
package me.skymc.taboolib.commands.internal;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Since 2018-05-07 21:36
 | 
			
		||||
 */
 | 
			
		||||
public class InternalMainCommand {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
package me.skymc.taboolib.commands.internal;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Since 2018-05-07 21:38
 | 
			
		||||
 */
 | 
			
		||||
public class InternalCommandExecutor {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,20 @@
 | 
			
		||||
package me.skymc.taboolib.commands.internal;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.command.Command;
 | 
			
		||||
import org.bukkit.command.CommandSender;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Bkm016
 | 
			
		||||
 * @since 2018-04-17
 | 
			
		||||
 */
 | 
			
		||||
public interface InternalCommand {
 | 
			
		||||
	
 | 
			
		||||
	String getLabel();
 | 
			
		||||
	
 | 
			
		||||
	String getDescription();
 | 
			
		||||
	
 | 
			
		||||
	InternalCommandArgument[] getArguments();
 | 
			
		||||
	
 | 
			
		||||
	void onCommand(CommandSender sender, Command command, String label, String[] args);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,51 @@
 | 
			
		||||
package me.skymc.taboolib.commands.internal;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.command.CommandSender;
 | 
			
		||||
import org.bukkit.command.ConsoleCommandSender;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
import java.util.stream.IntStream;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Bkm016
 | 
			
		||||
 * @since 2018-04-17
 | 
			
		||||
 */
 | 
			
		||||
public abstract class InternalCommandExecutor implements InternalCommand {
 | 
			
		||||
 | 
			
		||||
    public InternalCommandType getType() {
 | 
			
		||||
        return InternalCommandType.ALL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean requiredPlayer() {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isParameterConform(String[] args) {
 | 
			
		||||
        return IntStream.range(0, getArguments().length).noneMatch(i -> getArguments()[i].isRequired() && (args == null || args.length <= i));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isConfirmType(CommandSender sender, InternalCommandType commandType) {
 | 
			
		||||
        return commandType == InternalCommandType.ALL || sender instanceof ConsoleCommandSender && commandType == InternalCommandType.CONSOLE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<String> getTabCompleter(List<InternalCommandExecutor> internalCommandExecutors, String[] args) {
 | 
			
		||||
        return args.length == 1 ? internalCommandExecutors.stream().filter(internalCommandExecutor -> internalCommandExecutor != null && (args[0].isEmpty() || internalCommandExecutor.getLabel().startsWith(args[0]))).map(InternalCommand::getLabel).collect(Collectors.toList()) : null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getCommandString(String label) {
 | 
			
		||||
        StringBuilder stringBuilder = new StringBuilder();
 | 
			
		||||
        stringBuilder.append("§f /");
 | 
			
		||||
        stringBuilder.append(label);
 | 
			
		||||
        stringBuilder.append(" ");
 | 
			
		||||
        stringBuilder.append(getLabel());
 | 
			
		||||
        stringBuilder.append(" ");
 | 
			
		||||
        for (InternalCommandArgument parameter : getArguments()) {
 | 
			
		||||
            stringBuilder.append(parameter.toString());
 | 
			
		||||
            stringBuilder.append(" ");
 | 
			
		||||
        }
 | 
			
		||||
        stringBuilder.append("§6- §e");
 | 
			
		||||
        stringBuilder.append(getDescription());
 | 
			
		||||
        return stringBuilder.toString();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,11 @@
 | 
			
		||||
package me.skymc.taboolib.commands.internal;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Bkm016
 | 
			
		||||
 * @since 2018-04-17
 | 
			
		||||
 */
 | 
			
		||||
public enum InternalCommandType {
 | 
			
		||||
	
 | 
			
		||||
	CONSOLE, PLAYER, ALL
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
package me.skymc.taboolib.commands.plugin;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Since 2018-05-07 20:14
 | 
			
		||||
 */
 | 
			
		||||
public class TabooLibPluginCommand {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -68,7 +68,7 @@ public class ConfigUtils {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static MemoryConfiguration mapToConf(Map<String, Object> map) {
 | 
			
		||||
        MemoryConfiguration configuration = new MemoryConfiguration();
 | 
			
		||||
        YamlConfiguration configuration = new YamlConfiguration();
 | 
			
		||||
        convertMapsToSections(map, configuration);
 | 
			
		||||
        return configuration;
 | 
			
		||||
    }
 | 
			
		||||
@@ -112,13 +112,24 @@ public class ConfigUtils {
 | 
			
		||||
        return objToMap(object, Modifier.TRANSIENT & Modifier.STATIC & Ref.ACC_SYNTHETIC);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SuppressWarnings("unchecked")
 | 
			
		||||
    public static Map<String, Object> objToMap(Object object, int excludedModifiers) {
 | 
			
		||||
        Map<String, Object> map = Maps.newHashMap();
 | 
			
		||||
        if (object instanceof Map) {
 | 
			
		||||
            ((Map<String, ?>) object).forEach((k, v) -> map.put(k, objToMap(v, excludedModifiers)));
 | 
			
		||||
            return map;
 | 
			
		||||
        }
 | 
			
		||||
        if (object instanceof ConfigurationSection) {
 | 
			
		||||
            map.putAll(objToMap(((ConfigurationSection) object).getValues(false), excludedModifiers));
 | 
			
		||||
            return map;
 | 
			
		||||
        }
 | 
			
		||||
        for (Field field : Ref.getDeclaredFields(object.getClass(), excludedModifiers, false)) {
 | 
			
		||||
            try {
 | 
			
		||||
                if (!field.isAccessible()) field.setAccessible(true);
 | 
			
		||||
                Object obj = field.get(object);
 | 
			
		||||
                if (obj instanceof Property) obj = ((Property) obj).get();
 | 
			
		||||
                if (obj instanceof ConfigurationSection)
 | 
			
		||||
                    obj = objToMap(((ConfigurationSection) obj).getValues(false), excludedModifiers);
 | 
			
		||||
                map.put(Ref.getSerializedName(field), obj);
 | 
			
		||||
            } catch (IllegalAccessException ignored) {
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										49
									
								
								src/main/java/me/skymc/taboolib/string/ArrayUtils.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/main/java/me/skymc/taboolib/string/ArrayUtils.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
package me.skymc.taboolib.string;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Bkm016
 | 
			
		||||
 * @since 2018-04-16
 | 
			
		||||
 */
 | 
			
		||||
public class ArrayUtils {
 | 
			
		||||
	
 | 
			
		||||
	@SuppressWarnings("unchecked")
 | 
			
		||||
	public static <T> List<T> asList(T... args) {
 | 
			
		||||
		List<T> list = new ArrayList<>();
 | 
			
		||||
		for (T value : args) {
 | 
			
		||||
			list.add(value);
 | 
			
		||||
		}
 | 
			
		||||
		return list;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static String[] addFirst(String[] args, String... value) {
 | 
			
		||||
		if (args.length < 1) {
 | 
			
		||||
			return value;
 | 
			
		||||
		}
 | 
			
		||||
		List<String> list = asList(args);
 | 
			
		||||
		for (int i = value.length - 1 ; i >= 0 ; i--) {
 | 
			
		||||
			list.add(0, value[i]);
 | 
			
		||||
		}
 | 
			
		||||
		return list.toArray(new String[0]);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static String[] removeFirst(String[] args) {
 | 
			
		||||
		if (args.length <= 1) {
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
		List<String> list = asList(args);
 | 
			
		||||
		list.remove(0);
 | 
			
		||||
		return list.toArray(new String[0]);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static String arrayJoin(String[] args, int start) {
 | 
			
		||||
		StringBuilder stringBuilder = new StringBuilder();
 | 
			
		||||
		for (int i = start ; i < args.length ; i++) {
 | 
			
		||||
			stringBuilder.append(args[i]);
 | 
			
		||||
			stringBuilder.append(" ");
 | 
			
		||||
		}
 | 
			
		||||
		return stringBuilder.toString().trim();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										509
									
								
								src/main/java/org/javalite/activejdbc/MetaModel.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										509
									
								
								src/main/java/org/javalite/activejdbc/MetaModel.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,509 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2009-2018 Igor Polevoy
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
*/
 | 
			
		||||
package org.javalite.activejdbc;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.plugin.Plugin;
 | 
			
		||||
import org.javalite.activejdbc.annotations.*;
 | 
			
		||||
import org.javalite.activejdbc.associations.Many2ManyAssociation;
 | 
			
		||||
import org.javalite.activejdbc.associations.OneToManyAssociation;
 | 
			
		||||
import org.javalite.activejdbc.associations.OneToManyPolymorphicAssociation;
 | 
			
		||||
import org.javalite.activejdbc.dialects.Dialect;
 | 
			
		||||
import org.javalite.activejdbc.logging.LogFilter;
 | 
			
		||||
import org.javalite.activejdbc.logging.LogLevel;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
 | 
			
		||||
import java.io.Serializable;
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
import java.util.Map.Entry;
 | 
			
		||||
 | 
			
		||||
import static org.javalite.common.Inflector.singularize;
 | 
			
		||||
import static org.javalite.common.Inflector.tableize;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
public class MetaModel implements Serializable {
 | 
			
		||||
    private static final Logger LOGGER = LoggerFactory.getLogger(MetaModel.class);
 | 
			
		||||
    private static final ThreadLocal<HashMap<Class, String>> shardingTableNamesTL = new ThreadLocal<>();
 | 
			
		||||
    private final List<Association> associations = new ArrayList<>();
 | 
			
		||||
    private final String idName;
 | 
			
		||||
    private final String[] compositeKeys;
 | 
			
		||||
    private final String tableName, dbType, dbName;
 | 
			
		||||
    private final Class<? extends Model> modelClass;
 | 
			
		||||
    private final boolean cached;
 | 
			
		||||
    private final String idGeneratorCode;
 | 
			
		||||
    private final String versionColumn;
 | 
			
		||||
    private Map<String, ColumnMetadata> columnMetadata;
 | 
			
		||||
    private Set<String> attributeNamesNoId;
 | 
			
		||||
    private String[] partitionIDs = null;
 | 
			
		||||
 | 
			
		||||
    protected MetaModel(String dbName, Class<? extends Model> modelClass, String dbType) {
 | 
			
		||||
        this.modelClass = modelClass;
 | 
			
		||||
        this.idName = findIdName(modelClass);
 | 
			
		||||
        this.compositeKeys = findCompositeKeys(modelClass);
 | 
			
		||||
        this.tableName = findTableName(modelClass);
 | 
			
		||||
        this.dbType = dbType;
 | 
			
		||||
        this.cached = isCached(modelClass);
 | 
			
		||||
        this.dbName = dbName;
 | 
			
		||||
        this.idGeneratorCode = findIdGeneratorCode(modelClass);
 | 
			
		||||
        this.versionColumn = findVersionColumn(modelClass);
 | 
			
		||||
        this.partitionIDs = findPartitionIDs();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static Map<Class, String> getTableNamesMap() {
 | 
			
		||||
        if (shardingTableNamesTL.get() == null)
 | 
			
		||||
            shardingTableNamesTL.set(new HashMap<>());
 | 
			
		||||
        return shardingTableNamesTL.get();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected static String getDbName(Class<? extends Model> modelClass) {
 | 
			
		||||
        DbName dbNameAnnotation = modelClass.getAnnotation(DbName.class);
 | 
			
		||||
        return dbNameAnnotation == null ? DB.DEFAULT_NAME : dbNameAnnotation.value();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private String[] findPartitionIDs() {
 | 
			
		||||
        PartitionIDs partitionIDs = modelClass.getAnnotation(PartitionIDs.class);
 | 
			
		||||
        return partitionIDs != null ? partitionIDs.value() : null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean hasPartitionIDs() {
 | 
			
		||||
        return partitionIDs != null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String[] getPartitionIDs() {
 | 
			
		||||
        return partitionIDs;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * <p>
 | 
			
		||||
     * <strong>This feature is for sharding!</strong>
 | 
			
		||||
     * <br>
 | 
			
		||||
     * Do not use it to set table names <em>willy-nilly</em>!
 | 
			
		||||
     * </p>
 | 
			
		||||
     *
 | 
			
		||||
     * <p>
 | 
			
		||||
     * Sets a table name for this model. The table name is attached to a current thread and will remain there
 | 
			
		||||
     * until it is set with a different value or cleared with {@link #clearShardTableName()} method.
 | 
			
		||||
     * Table name set with this method overrides a table name naturally mapped to this model.
 | 
			
		||||
     * </p>
 | 
			
		||||
     * <p>
 | 
			
		||||
     * Method {@link #getTableName()} will return this value for all operations related to this table.
 | 
			
		||||
     * </p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param tableName name of a table this model will read from current thread.
 | 
			
		||||
     */
 | 
			
		||||
    public void setShardTableName(String tableName) {
 | 
			
		||||
        getTableNamesMap().put(modelClass, tableName);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Clears sharding name of table attached to current thread.
 | 
			
		||||
     * The name was supposedly attached by the {@link #setShardTableName(String)}
 | 
			
		||||
     * method. After execution of this class, the method {@link #getTableName()} will be
 | 
			
		||||
     * returning the value this {@link MetaModel} was initialized with during teh bootstrap phase.
 | 
			
		||||
     */
 | 
			
		||||
    public void clearShardTableName() {
 | 
			
		||||
        getTableNamesMap().remove(modelClass);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean isCached(Class<? extends Model> modelClass) {
 | 
			
		||||
        return null != modelClass.getAnnotation(Cached.class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private String findIdName(Class<? extends Model> modelClass) {
 | 
			
		||||
        IdName idNameAnnotation = modelClass.getAnnotation(IdName.class);
 | 
			
		||||
        return idNameAnnotation == null ? "id" : idNameAnnotation.value();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private String[] findCompositeKeys(Class<? extends Model> modelClass) {
 | 
			
		||||
        CompositePK compositeKeysAnnotation = modelClass.getAnnotation(CompositePK.class);
 | 
			
		||||
        return compositeKeysAnnotation == null ? null : compositeKeysAnnotation.value();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Table name with plugin name prefix
 | 
			
		||||
     *
 | 
			
		||||
     * @return table name
 | 
			
		||||
     */
 | 
			
		||||
    private String findTableName(Class<? extends Model> modelClass) {
 | 
			
		||||
        Table tableAnnotation = modelClass.getAnnotation(Table.class);
 | 
			
		||||
        String prefix = "";
 | 
			
		||||
        try {
 | 
			
		||||
            Field field = modelClass.getClassLoader().getClass().getDeclaredField("plugin");
 | 
			
		||||
            field.setAccessible(true);
 | 
			
		||||
            Plugin plugin = (Plugin) field.get(modelClass.getClassLoader());
 | 
			
		||||
            prefix = tableize(plugin.getName()) + "_";
 | 
			
		||||
        } catch (Throwable ignored) {
 | 
			
		||||
        }
 | 
			
		||||
        return prefix + (tableAnnotation == null ? tableize(modelClass.getSimpleName()) : tableAnnotation.value());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private String findIdGeneratorCode(Class<? extends Model> modelClass) {
 | 
			
		||||
        IdGenerator idGenerator = modelClass.getAnnotation(IdGenerator.class);
 | 
			
		||||
        return idGenerator == null ? null : idGenerator.value();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private String findVersionColumn(Class<? extends Model> modelClass) {
 | 
			
		||||
        VersionColumn vc = modelClass.getAnnotation(VersionColumn.class);
 | 
			
		||||
        return vc == null ? "record_version" : vc.value();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return name of the column for optimistic locking record version
 | 
			
		||||
     */
 | 
			
		||||
    public String getVersionColumn() {
 | 
			
		||||
        return versionColumn;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getIdGeneratorCode() {
 | 
			
		||||
        return idGeneratorCode;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getDbName() {
 | 
			
		||||
        return dbName;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean cached() {
 | 
			
		||||
        return cached;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Class<? extends Model> getModelClass() {
 | 
			
		||||
        return modelClass;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns table name currently associated with this model.
 | 
			
		||||
     * Table name can be modified for sharding using {@link #setShardTableName(String)}
 | 
			
		||||
     *
 | 
			
		||||
     * @return table name currently associated with this model.
 | 
			
		||||
     */
 | 
			
		||||
    public String getTableName() {
 | 
			
		||||
        return getTableNamesMap().getOrDefault(modelClass, tableName);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected boolean tableExists() {
 | 
			
		||||
        return columnMetadata != null && columnMetadata.isEmpty();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Finds all attribute names except for id.
 | 
			
		||||
     *
 | 
			
		||||
     * @return all attribute names except for id.
 | 
			
		||||
     */
 | 
			
		||||
    public Set<String> getAttributeNamesSkipId() {
 | 
			
		||||
        if (attributeNamesNoId == null) {//no one cares about unfortunate multi-threading timing with 2 instances created
 | 
			
		||||
            //if someone does, use DCL with volatile
 | 
			
		||||
            Set<String> attributesNames = new CaseInsensitiveSet(getAttributeNames());
 | 
			
		||||
            attributesNames.remove(getIdName());
 | 
			
		||||
            attributeNamesNoId = attributesNames;
 | 
			
		||||
        }
 | 
			
		||||
        return attributeNamesNoId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Convenience method. Calls {@link #getAttributeNamesSkipGenerated(boolean)} and passes <code>true</code> as argument.
 | 
			
		||||
     *
 | 
			
		||||
     * @return list of all attributes except id, created_at, updated_at and record_version.
 | 
			
		||||
     */
 | 
			
		||||
    public Set<String> getAttributeNamesSkipGenerated() {
 | 
			
		||||
        return getAttributeNamesSkipGenerated(true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Finds all attribute names except managed like <code>id</code>,
 | 
			
		||||
     * <code>created_at</code>, <code>updated_at</code> and <code>record_version</code>, depending on argument.
 | 
			
		||||
     *
 | 
			
		||||
     * @param managed if true, time managed attributes <code>created_at</code> and <code>updated_at</code> will not be included (they are managed automatically).
 | 
			
		||||
     *                If false (not managed) <code>created_at</code> and <code>updated_at</code> will be included in output.
 | 
			
		||||
     * @return list of all attributes except <code>id</code>, <code>created_at</code>, <code>updated_at</code> and
 | 
			
		||||
     * <code>record_version</code>, depending on argument.
 | 
			
		||||
     */
 | 
			
		||||
    public Set<String> getAttributeNamesSkipGenerated(boolean managed) {
 | 
			
		||||
        //TODO: can cache this, but will need a cache for managed=true an another for managed=false
 | 
			
		||||
        Set<String> attributesNames = new CaseInsensitiveSet(getAttributeNamesSkipId());
 | 
			
		||||
 | 
			
		||||
        if (managed) {
 | 
			
		||||
            attributesNames.remove("created_at");
 | 
			
		||||
            attributesNames.remove("updated_at");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        attributesNames.remove(versionColumn);
 | 
			
		||||
        return attributesNames;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Finds all attribute names except those provided as arguments.
 | 
			
		||||
     *
 | 
			
		||||
     * @return list of all attributes except those provided as arguments.
 | 
			
		||||
     */
 | 
			
		||||
    public Set<String> getAttributeNamesSkip(String... names) {
 | 
			
		||||
        Set<String> attributes = new CaseInsensitiveSet(getAttributeNames());
 | 
			
		||||
        for (String name : names) {
 | 
			
		||||
            attributes.remove(name);
 | 
			
		||||
        }
 | 
			
		||||
        return attributes;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns true if this model supports optimistic locking, false if not
 | 
			
		||||
     *
 | 
			
		||||
     * @return true if this model supports optimistic locking, false if not
 | 
			
		||||
     */
 | 
			
		||||
    public boolean isVersioned() {
 | 
			
		||||
        return columnMetadata != null && columnMetadata.containsKey(versionColumn);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Retrieves all attribute names.
 | 
			
		||||
     *
 | 
			
		||||
     * @return all attribute names.
 | 
			
		||||
     */
 | 
			
		||||
    protected Set<String> getAttributeNames() {
 | 
			
		||||
        if (columnMetadata == null || columnMetadata.isEmpty())
 | 
			
		||||
            throw new InitException("Failed to find table: " + getTableName());
 | 
			
		||||
        return Collections.unmodifiableSet(columnMetadata.keySet());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getIdName() {
 | 
			
		||||
        return idName;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns optional composite primary key class
 | 
			
		||||
     *
 | 
			
		||||
     * @return composite primary key class
 | 
			
		||||
     */
 | 
			
		||||
    public String[] getCompositeKeys() {
 | 
			
		||||
        return compositeKeys;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns association of this table with the target table. Will return null if there is no association.
 | 
			
		||||
     *
 | 
			
		||||
     * @param targetModelClass association of this model and the target model.
 | 
			
		||||
     * @param associationClass class of association in requested.
 | 
			
		||||
     * @return association of this table with the target table. Will return null if there is no association with target
 | 
			
		||||
     * table and specified type.
 | 
			
		||||
     */
 | 
			
		||||
    public <A extends Association> A getAssociationForTarget(Class<? extends Model> targetModelClass, Class<A> associationClass) {
 | 
			
		||||
        Association result = null;
 | 
			
		||||
        for (Association association : associations) {
 | 
			
		||||
            if (association.getClass().equals(associationClass) && association.getTargetClass().equals(targetModelClass)) {
 | 
			
		||||
                result = association;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return (A) result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns association of this table with the target table. Will return null if there is no association.
 | 
			
		||||
     *
 | 
			
		||||
     * @param targetClass association of this model and the target model.
 | 
			
		||||
     * @return association of this table with the target table. Will return null if there is no association with target
 | 
			
		||||
     * table and specified type.
 | 
			
		||||
     */
 | 
			
		||||
    public <A extends Association> A getAssociationForTarget(Class<? extends Model> targetClass) {
 | 
			
		||||
        Association result = null;
 | 
			
		||||
        for (Association association : associations) {
 | 
			
		||||
            if (association.getTargetClass().equals(targetClass)) {
 | 
			
		||||
                result = association;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return (A) result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns associations of this table with the target table. It is possible
 | 
			
		||||
     * to have more than one association to a target table if a target table is the same as source. Usually this
 | 
			
		||||
     * happens when tree structures are stored in the same table (category has many categories).
 | 
			
		||||
     *
 | 
			
		||||
     * @param targetModelClass association of this model and the target model.
 | 
			
		||||
     * @return list of associations of this table with the target table. Will return empty list if none found.
 | 
			
		||||
     * table and specified type.
 | 
			
		||||
     */
 | 
			
		||||
    public List<Association> getAssociationsForTarget(Class<? extends Model> targetModelClass) {
 | 
			
		||||
        List<Association> result = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
        for (Association association : associations) {
 | 
			
		||||
            if (association.getTargetClass().equals(targetModelClass)) {
 | 
			
		||||
                result.add(association);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected void addAssociation(Association association) {
 | 
			
		||||
        if (!associations.contains(association)) {
 | 
			
		||||
            LogFilter.log(LOGGER, LogLevel.INFO, "Association found: {}", association);
 | 
			
		||||
            associations.add(association);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * returns true if this attribute is present in this meta model. This method i case insensitive.
 | 
			
		||||
     *
 | 
			
		||||
     * @param attribute attribute name, case insensitive.
 | 
			
		||||
     * @return true if this attribute is present in this meta model, false of not.
 | 
			
		||||
     */
 | 
			
		||||
    boolean hasAttribute(String attribute) {
 | 
			
		||||
        if (columnMetadata != null) {
 | 
			
		||||
            if (columnMetadata.containsKey(attribute)) {
 | 
			
		||||
                return true;
 | 
			
		||||
            } else if (attribute.startsWith("\"") && attribute.endsWith("\"")) {
 | 
			
		||||
                return columnMetadata.containsKey(attribute.substring(1, attribute.length() - 1));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected boolean hasAssociation(Class<? extends Model> targetClass, Class<? extends Association> associationClass) {
 | 
			
		||||
        for (Association association : associations) {
 | 
			
		||||
            if (association.getTargetClass().equals(targetClass) &&
 | 
			
		||||
                    association.getClass().equals(associationClass)) return true;
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        final StringBuilder t = new StringBuilder();
 | 
			
		||||
        t.append("MetaModel: ").append(tableName).append(", ").append(modelClass).append("\n");
 | 
			
		||||
        if (columnMetadata != null) {
 | 
			
		||||
            for (Entry<String, ColumnMetadata> metadata : columnMetadata.entrySet()) {
 | 
			
		||||
                t.append(metadata.getValue()).append(", ");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return t.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * FK name is a foreign key name used in relationships as a foreign key column in a child table (table represented by this
 | 
			
		||||
     * instance is a parent table).
 | 
			
		||||
     * The FK name is derived using {@link org.javalite.common.Inflector}: It is a singular version of this table name plus "_id".
 | 
			
		||||
     *
 | 
			
		||||
     * @return foreign key name used in relationships as a foreign key column in a child table.
 | 
			
		||||
     */
 | 
			
		||||
    public String getFKName() {
 | 
			
		||||
        return singularize(getTableName()).toLowerCase() + "_id";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected List<OneToManyAssociation> getOneToManyAssociations(List<Association> exclusions) {
 | 
			
		||||
        List<OneToManyAssociation> one2Manies = new ArrayList<>();
 | 
			
		||||
        for (Association association : associations) {
 | 
			
		||||
            if (association.getClass().equals(OneToManyAssociation.class) && !exclusions.contains(association)) {
 | 
			
		||||
                one2Manies.add((OneToManyAssociation) association);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return one2Manies;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected List<OneToManyPolymorphicAssociation> getPolymorphicAssociations(List<Association> exclusions) {
 | 
			
		||||
        List<OneToManyPolymorphicAssociation> one2Manies = new ArrayList<>();
 | 
			
		||||
        for (Association association : associations) {
 | 
			
		||||
            if (association.getClass().equals(OneToManyPolymorphicAssociation.class) && !exclusions.contains(association)) {
 | 
			
		||||
                one2Manies.add((OneToManyPolymorphicAssociation) association);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return one2Manies;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected List<Many2ManyAssociation> getManyToManyAssociations(List<Association> excludedAssociations) {
 | 
			
		||||
        List<Many2ManyAssociation> many2Manies = new ArrayList<>();
 | 
			
		||||
        for (Association association : associations) {
 | 
			
		||||
            if (association.getClass().equals(Many2ManyAssociation.class) && !excludedAssociations.contains(association)) {
 | 
			
		||||
                many2Manies.add((Many2ManyAssociation) association);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return many2Manies;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getDbType() {
 | 
			
		||||
        return dbType;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Dialect getDialect() {
 | 
			
		||||
        return Registry.instance().getConfiguration().getDialect(this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected List<Association> getAssociations() {
 | 
			
		||||
        return Collections.unmodifiableList(associations);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks if this model has a named attribute that has the same name as argument.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * Throws <code>IllegalArgumentException</code> in case it does not find it.
 | 
			
		||||
     *
 | 
			
		||||
     * @param attribute name  of attribute or association target.
 | 
			
		||||
     */
 | 
			
		||||
    protected void checkAttribute(String attribute) {
 | 
			
		||||
        if (!hasAttribute(attribute)) {
 | 
			
		||||
            String sb = "Attribute: '" + attribute + "' is not defined in model: '" + getModelClass() + ". "
 | 
			
		||||
                    + "Available attributes: " + getAttributeNames();
 | 
			
		||||
            throw new IllegalArgumentException(sb);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Provides column metadata map, keyed by attribute names.
 | 
			
		||||
     * Table columns correspond to ActiveJDBC model attributes.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Provides column metadata map, keyed by attribute names.
 | 
			
		||||
     */
 | 
			
		||||
    public Map<String, ColumnMetadata> getColumnMetadata() {
 | 
			
		||||
        if (columnMetadata == null || columnMetadata.isEmpty())
 | 
			
		||||
            throw new InitException("Failed to find table: " + getTableName());
 | 
			
		||||
        return Collections.unmodifiableMap(columnMetadata);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void setColumnMetadata(Map<String, ColumnMetadata> columnMetadata) {
 | 
			
		||||
        this.columnMetadata = columnMetadata;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks if there is association to the target model class.,
 | 
			
		||||
     *
 | 
			
		||||
     * @param targetModelClass class of a model that will be checked for association from current model.
 | 
			
		||||
     * @return true if any association exists such that the current model is a source and targetModelClass is a target.
 | 
			
		||||
     */
 | 
			
		||||
    public boolean isAssociatedTo(Class<? extends Model> targetModelClass) {
 | 
			
		||||
 | 
			
		||||
        if (targetModelClass == null) {
 | 
			
		||||
            throw new NullPointerException();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (Association association : associations) {
 | 
			
		||||
            if (association.getTargetClass().equals(targetModelClass)) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void removeAssociationForTarget(Class<? extends Model> modelClass) {
 | 
			
		||||
        Association association = getAssociationForTarget(modelClass);
 | 
			
		||||
        if (association != null) {
 | 
			
		||||
            associations.remove(association);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user