TabooMan!
This commit is contained in:
commit
8c6518ffc5
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
|
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||||
hs_err_pid*
|
hs_err_pid*
|
||||||
.gradle/4.3.1/
|
.gradle/4.3.1/
|
||||||
.idea/TabooLib.iml
|
.idea
|
||||||
.idea/misc.xml
|
target/TabooLib-3.832-shaded.jar
|
||||||
.idea/modules.xml
|
target/TabooLib-3.832.jar
|
||||||
.idea/workspace.xml
|
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
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
<inspection_tool class="AlibabaClassNamingShouldBeCamel" enabled="false" level="MAJOR" enabled_by_default="false" />
|
<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="AlibabaConstantFieldShouldBeUpperCase" enabled="false" level="CRITICAL" enabled_by_default="false" />
|
||||||
<inspection_tool class="AlibabaEnumConstantsMustHaveComment" 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="AlibabaUndefineMagicConstant" enabled="false" level="MAJOR" enabled_by_default="false" />
|
||||||
<inspection_tool class="JavaDoc" enabled="false" level="WARNING" enabled_by_default="false">
|
<inspection_tool class="JavaDoc" enabled="false" level="WARNING" enabled_by_default="false">
|
||||||
<option name="TOP_LEVEL_CLASS_OPTIONS">
|
<option name="TOP_LEVEL_CLASS_OPTIONS">
|
||||||
|
13
.idea/libraries/Maven__com_h2database_h2_1_4_197.xml
Normal file
13
.idea/libraries/Maven__com_h2database_h2_1_4_197.xml
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
Normal file
13
.idea/libraries/Maven__javax_servlet_servlet_api_2_5.xml
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>
|
@ -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>
|
@ -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
Normal file
13
.idea/libraries/Maven__org_javalite_activejdbc_2_0.xml
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
Normal file
13
.idea/libraries/Maven__org_javalite_app_config_2_0.xml
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
Normal file
13
.idea/libraries/Maven__org_javalite_javalite_common_2_0.xml
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>
|
<artifactId>HikariCP</artifactId>
|
||||||
<version>3.1.0</version>
|
<version>3.1.0</version>
|
||||||
</dependency>
|
</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>
|
<dependency>
|
||||||
<groupId>com.ilummc.eagletdl</groupId>
|
<groupId>com.ilummc.eagletdl</groupId>
|
||||||
<artifactId>EagletCore</artifactId>
|
<artifactId>EagletCore</artifactId>
|
||||||
|
@ -3,6 +3,7 @@ package com.ilummc.tlib;
|
|||||||
import com.ilummc.tlib.annotations.Dependency;
|
import com.ilummc.tlib.annotations.Dependency;
|
||||||
import com.ilummc.tlib.compat.PlaceholderHook;
|
import com.ilummc.tlib.compat.PlaceholderHook;
|
||||||
import com.ilummc.tlib.config.TLibConfig;
|
import com.ilummc.tlib.config.TLibConfig;
|
||||||
|
import com.ilummc.tlib.db.Pool;
|
||||||
import com.ilummc.tlib.filter.TLoggerFilter;
|
import com.ilummc.tlib.filter.TLoggerFilter;
|
||||||
import com.ilummc.tlib.inject.TConfigWatcher;
|
import com.ilummc.tlib.inject.TConfigWatcher;
|
||||||
import com.ilummc.tlib.inject.TDependencyInjector;
|
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 = "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 = "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.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 {
|
public class TLib {
|
||||||
|
|
||||||
private static TLib tLib;
|
private static TLib tLib;
|
||||||
@ -60,10 +71,20 @@ public class TLib {
|
|||||||
TLoggerFilter.init();
|
TLoggerFilter.init();
|
||||||
TLocaleLoader.init();
|
TLocaleLoader.init();
|
||||||
PlaceholderHook.init();
|
PlaceholderHook.init();
|
||||||
|
TLocaleLoader.load(Main.getInst(), false);
|
||||||
TDependencyInjector.inject(Main.getInst(), tLib);
|
TDependencyInjector.inject(Main.getInst(), tLib);
|
||||||
|
|
||||||
|
// init database
|
||||||
|
try {
|
||||||
|
Pool.init();
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void unload() {
|
public static void unload() {
|
||||||
|
Pool.unload();
|
||||||
tLib.getConfigWatcher().unregisterAll();
|
tLib.getConfigWatcher().unregisterAll();
|
||||||
TDependencyInjector.eject(Main.getInst(), tLib);
|
TDependencyInjector.eject(Main.getInst(), tLib);
|
||||||
}
|
}
|
||||||
|
@ -9,13 +9,28 @@ import com.ilummc.tlib.annotations.TConfig;
|
|||||||
@TConfig(name = "tlib.yml", listenChanges = true)
|
@TConfig(name = "tlib.yml", listenChanges = true)
|
||||||
public class TLibConfig {
|
public class TLibConfig {
|
||||||
|
|
||||||
private boolean enablePlaceholderHookByDefault = false;
|
@Getter
|
||||||
|
private String dataSourceClassName;
|
||||||
|
|
||||||
public void setEnablePlaceholderHookByDefault(boolean enablePlaceholderHookByDefault) {
|
@Getter
|
||||||
this.enablePlaceholderHookByDefault = enablePlaceholderHookByDefault;
|
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;
|
package com.ilummc.tlib.inject;
|
||||||
|
|
||||||
import com.google.common.io.Files;
|
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.annotations.TConfig;
|
||||||
import com.ilummc.tlib.resources.TLocale;
|
import com.ilummc.tlib.resources.TLocale;
|
||||||
import me.skymc.taboolib.fileutils.ConfigUtils;
|
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.configuration.file.YamlConfiguration;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.yaml.snakeyaml.DumperOptions;
|
import org.yaml.snakeyaml.DumperOptions;
|
||||||
import org.yaml.snakeyaml.Yaml;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class TConfigInjector {
|
public class TConfigInjector {
|
||||||
@ -106,7 +108,7 @@ public class TConfigInjector {
|
|||||||
try {
|
try {
|
||||||
TConfig config = object.getClass().getAnnotation(TConfig.class);
|
TConfig config = object.getClass().getAnnotation(TConfig.class);
|
||||||
Validate.notNull(config);
|
Validate.notNull(config);
|
||||||
return ConfigUtils.objToConf(object).getValues(false);
|
return ConfigUtils.objToMap(ConfigUtils.objToConf(object).getValues(false), config.excludeModifiers());
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
TLocale.Logger.warn("CONFIG.SAVE-FAIL-NO-ANNOTATION", plugin.toString(), object.getClass().getSimpleName());
|
TLocale.Logger.warn("CONFIG.SAVE-FAIL-NO-ANNOTATION", plugin.toString(), object.getClass().getSimpleName());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -118,16 +120,12 @@ public class TConfigInjector {
|
|||||||
public static void saveConfig(Plugin plugin, Object object) throws IOException, NullPointerException {
|
public static void saveConfig(Plugin plugin, Object object) throws IOException, NullPointerException {
|
||||||
TConfig config = object.getClass().getAnnotation(TConfig.class);
|
TConfig config = object.getClass().getAnnotation(TConfig.class);
|
||||||
Validate.notNull(config);
|
Validate.notNull(config);
|
||||||
Object obj = serialize(plugin, object);
|
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
|
||||||
Validate.notNull(obj);
|
Map map = gson.fromJson(gson.toJson(object), HashMap.class);
|
||||||
|
YamlConfiguration configuration = (YamlConfiguration) ConfigUtils.mapToConf(map);
|
||||||
File target = new File(plugin.getDataFolder(), config.name());
|
File target = new File(plugin.getDataFolder(), config.name());
|
||||||
if (!target.exists()) target.createNewFile();
|
if (!target.exists()) target.createNewFile();
|
||||||
DumperOptions options = new DumperOptions();
|
byte[] arr = configuration.saveToString().getBytes(config.charset());
|
||||||
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
|
||||||
options.setAllowUnicode(false);
|
|
||||||
Yaml yaml = new Yaml(options);
|
|
||||||
String str = yaml.dump(obj);
|
|
||||||
byte[] arr = str.getBytes(config.charset());
|
|
||||||
Files.write(arr, target);
|
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) {
|
public static MemoryConfiguration mapToConf(Map<String, Object> map) {
|
||||||
MemoryConfiguration configuration = new MemoryConfiguration();
|
YamlConfiguration configuration = new YamlConfiguration();
|
||||||
convertMapsToSections(map, configuration);
|
convertMapsToSections(map, configuration);
|
||||||
return configuration;
|
return configuration;
|
||||||
}
|
}
|
||||||
@ -112,13 +112,24 @@ public class ConfigUtils {
|
|||||||
return objToMap(object, Modifier.TRANSIENT & Modifier.STATIC & Ref.ACC_SYNTHETIC);
|
return objToMap(object, Modifier.TRANSIENT & Modifier.STATIC & Ref.ACC_SYNTHETIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public static Map<String, Object> objToMap(Object object, int excludedModifiers) {
|
public static Map<String, Object> objToMap(Object object, int excludedModifiers) {
|
||||||
Map<String, Object> map = Maps.newHashMap();
|
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)) {
|
for (Field field : Ref.getDeclaredFields(object.getClass(), excludedModifiers, false)) {
|
||||||
try {
|
try {
|
||||||
if (!field.isAccessible()) field.setAccessible(true);
|
if (!field.isAccessible()) field.setAccessible(true);
|
||||||
Object obj = field.get(object);
|
Object obj = field.get(object);
|
||||||
if (obj instanceof Property) obj = ((Property) obj).get();
|
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);
|
map.put(Ref.getSerializedName(field), obj);
|
||||||
} catch (IllegalAccessException ignored) {
|
} 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user